ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-08-04 03:39:32
Exec Total Coverage
Lines: 4060 5059 80.3%
Functions: 289 327 88.4%
Branches: 3115 5091 61.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 415 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 415 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 580 void maps_init_game_vars()
67 {
68 580 viewport = {};
69 580 viewport_mode = ViewportMode::CenterAndBound;
70 580 viewport_sprite_uid = 1;
71 580 currscr_for_passive_subscr = -1;
72 580 }
73
74 static region_ids_t current_region_ids;
75
76 14541353 static bool is_a_region(int map, int scr)
77 {
78 14541353 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 137747704 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 137746131 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 137746131 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 137733918 times.
137747704 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 69622154 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 69622153 times.
69622154 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 28854954 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 28839933 times.
✓ Branch 1 taken 15021 times.
✓ Branch 2 taken 461472 times.
✓ Branch 3 taken 28378461 times.
28854954 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 8979128755 bool is_in_scrolling_region()
115 {
116 8979128755 return cur_region.screen_count > 1;
117 }
118
119 76449194 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76199060 times.
✓ Branch 1 taken 250134 times.
76449194 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15583097 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 400226 times.
✓ Branch 1 taken 15182871 times.
15583097 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15181779 times.
✓ Branch 1 taken 1092 times.
15182871 if (map == cur_region.map) return current_region_ids[screen];
129
130 1092 return Regions[map].get_region_id(screen);
131 15583097 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 63880 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 63880 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63606 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
63880 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63606 region.region_id = 0;
145 63606 region.origin_screen = screen;
146 63606 region.origin_screen_x = screen % 16;
147 63606 region.origin_screen_y = screen / 16;
148 63606 region.screen_width = 1;
149 63606 region.screen_height = 1;
150 63606 region.screen_count = 1;
151 63606 region.width = 256;
152 63606 region.height = 176;
153 63606 region_scr_dx = 0;
154 63606 region_scr_dy = 0;
155 63606 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 63880 }
206
207 35668 void load_region(int dmap, int screen)
208 {
209 35668 clear_temporary_screens();
210
211 35668 int map = DMaps[dmap].map;
212 35668 current_region_ids = Regions[map].get_all_region_ids();
213
214 35668 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35668 cur_screen = cur_region.origin_screen;
216 35668 world_w = cur_region.width;
217 35668 world_h = cur_region.height;
218 35668 region_scr_count = cur_region.screen_count;
219 35668 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35668 region_num_rpos = cur_region.screen_count*176;
221 35668 scrolling_maze_last_solved_screen = 0;
222
223 35668 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 35902 times.
✓ Branch 1 taken 35668 times.
71570 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 36912 times.
✓ Branch 1 taken 35902 times.
72814 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 36912 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36912 times.
36912 if (screen < 136)
230 {
231 36912 screen_in_current_region[screen] = true;
232 36912 }
233 36912 }
234 35902 }
235
236 35668 mark_current_region_handles_dirty();
237 35668 }
238
239 35668 static void prepare_current_region_handles()
240 {
241 35668 current_region_rpos_handles_dirty = false;
242 35668 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36016 times.
✓ Branch 1 taken 35668 times.
71684 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 36912 times.
✓ Branch 1 taken 36016 times.
72928 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 36912 int screen = cur_screen + x + y*16;
248 36912 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 36912 times.
✓ Branch 1 taken 258384 times.
295296 for (int layer = 0; layer <= 6; layer++)
250 {
251 258384 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 83941 times.
✓ Branch 1 taken 174443 times.
258384 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 174443 times.
✗ Branch 1 not taken.
174443 if (layer == 0) break;
255 174443 continue;
256 }
257
258 83941 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 83941 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 83941 current_region_screen_count += 1;
261 83941 }
262
263 36912 int num_handles_for_scr = current_region_screen_count - index_start;
264 36912 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 36912 }
266 36016 }
267 35668 }
268
269 1775096687 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1775096687 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 10988902 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 10988902 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10988902 times.
10988902 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10988902 times.
10988902 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 10988902 return current_region_rpos_handles_scr[scr->screen];
289 10988902 }
290
291 35668 void mark_current_region_handles_dirty()
292 {
293 35668 current_region_rpos_handles_dirty = true;
294 35668 }
295
296 36806 void clear_temporary_screens()
297 {
298
2/2
✓ Branch 0 taken 35039312 times.
✓ Branch 1 taken 36806 times.
35076118 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 34984971 times.
✓ Branch 1 taken 54341 times.
35039312 if (temporary_screens[i])
301 {
302 54341 free(temporary_screens[i]);
303 54341 temporary_screens[i] = NULL;
304 54341 }
305 35039312 }
306
307 36806 origin_scr = nullptr;
308 36806 hero_scr = nullptr;
309 36806 }
310
311 27805 std::vector<mapscr*> take_temporary_scrs()
312 {
313
1/2
✓ Branch 0 taken 27805 times.
✗ Branch 1 not taken.
27805 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
314
2/2
✓ Branch 0 taken 27805 times.
✓ Branch 1 taken 26470360 times.
26498165 for (int i = 0; i < 136*7; i++)
315 26470360 temporary_screens[i] = nullptr;
316
317 27805 return screens;
318
1/2
✓ Branch 0 taken 27805 times.
✗ Branch 1 not taken.
27805 }
319
320 14475601 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
321 {
322 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
323
324
2/2
✓ Branch 0 taken 14429019 times.
✓ Branch 1 taken 46582 times.
14475601 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
325 14475601 viewport.w = 256;
326 14475601 viewport.h = 176 + (extended_height_mode ? 56 : 0);
327
328
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14475241 times.
14475601 if (viewport_mode == ViewportMode::Script)
329 360 return;
330
331
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14429079 times.
14475241 if (!is_a_region(DMaps[dmap].map, screen))
332 {
333 14429079 viewport.x = 0;
334 14429079 viewport.y = 0;
335 14429079 }
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
337 {
338 // Clamp the viewport to the edges of the region.
339
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
340
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
341 46162 }
342 else if (viewport_mode == ViewportMode::Center)
343 {
344 viewport.x = x - viewport.w/2;
345 viewport.y = y - viewport.h/2;
346 }
347 14475601 }
348
349 14475091 sprite* get_viewport_sprite()
350 {
351 14475091 sprite* spr = sprite::getByUID(viewport_sprite_uid);
352
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14475085 times.
14475091 if (!spr)
353 {
354 6 viewport_sprite_uid = 1; // Hero uid.
355 6 spr = &Hero;
356 6 }
357
358 14475091 return spr;
359 }
360
361 6 void set_viewport_sprite(sprite* spr)
362 {
363 6 viewport_sprite_uid = spr->uid;
364 6 }
365
366 14447286 void update_viewport()
367 {
368 14447286 sprite* spr = get_viewport_sprite();
369 14447286 int x = spr->x + spr->txsz*16/2;
370 14447286 int y = spr->y + spr->tysz*16/2;
371 14447286 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
372 14447286 }
373
374 14236925 void update_heroscr()
375 {
376 void playLevelMusic();
377
378 14236925 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
379 14236925 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
380 14236925 int dx = x / 256;
381 14236925 int dy = y / 176;
382 14236925 int new_screen = cur_screen + dx + dy * 16;
383
2/2
✓ Branch 0 taken 14229163 times.
✓ Branch 1 taken 7762 times.
14236925 if (maze_state.active == 1)
384 7762 new_screen = maze_state.scr->screen;
385
7/12
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14236709 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 216 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 216 times.
14236925 if (hero_screen != new_screen && dx >= 0 && dy >= 0 && dx < 16 && dy < 8 && is_in_current_region(new_screen))
386 {
387 216 region_scr_dx = dx;
388 216 region_scr_dy = dy;
389 216 hero_screen = new_screen;
390 216 prev_hero_scr = hero_scr;
391 216 hero_scr = get_scr(hero_screen);
392 216 Hero.screen_spawned = hero_screen;
393 216 playLevelMusic();
394 216 }
395
1/2
✓ Branch 0 taken 14236925 times.
✗ Branch 1 not taken.
14236925 if (game->get_regionmapping() == REGION_MAPPING_PHYSICAL)
396 mark_visited(new_screen); // Mark each screen the hero steps foot in as visited
397 14236925 }
398
399 4722 mapscr* determine_hero_screen_from_coords()
400 {
401 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
402 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
403 4722 int dx = x / 256;
404 4722 int dy = y / 176;
405 4722 return get_scr(cur_screen + dx + dy * 16);
406 }
407
408 26783 bool edge_of_region(direction dir)
409 {
410
2/2
✓ Branch 0 taken 26703 times.
✓ Branch 1 taken 80 times.
26783 if (!is_in_scrolling_region()) return true;
411
412 80 int screen_x = hero_screen % 16;
413 80 int screen_y = hero_screen / 16;
414
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
415
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
416
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
417
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
418
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
419 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
420 26783 }
421
422 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
423 // Coordinates are clamped to the world bounds.
424 211191607 int get_screen_for_world_xy(int x, int y)
425 {
426
2/2
✓ Branch 0 taken 188401995 times.
✓ Branch 1 taken 22789612 times.
211191607 if (!is_in_scrolling_region())
427 188401995 return cur_screen;
428
429 22789612 int dx = std::clamp(x, 0, world_w - 1) / 256;
430 22789612 int dy = std::clamp(y, 0, world_h - 1) / 176;
431 22789612 int origin_screen_x = cur_screen % 16;
432 22789612 int origin_screen_y = cur_screen / 16;
433 22789612 int scr_x = origin_screen_x + dx;
434 22789612 int scr_y = origin_screen_y + dy;
435 22789612 return map_scr_xy_to_index(scr_x, scr_y);
436 211191607 }
437
438 32518504 int get_screen_for_rpos(rpos_t rpos)
439 {
440 32518504 int origin_screen_x = cur_screen % 16;
441 32518504 int origin_screen_y = cur_screen / 16;
442 32518504 int screen = static_cast<int32_t>(rpos) / 176;
443 32518504 int scr_x = origin_screen_x + screen%cur_region.screen_width;
444 32518504 int scr_y = origin_screen_y + screen/cur_region.screen_width;
445 32518504 return map_scr_xy_to_index(scr_x, scr_y);
446 }
447
448 772452989 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
449 {
450 DCHECK_LAYER_ZERO_INDEX(layer);
451
2/2
✓ Branch 0 taken 740072445 times.
✓ Branch 1 taken 32380544 times.
772452989 if (!is_in_scrolling_region())
452 740072445 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
453 32380544 int screen = get_screen_for_rpos(rpos);
454 32380544 mapscr* scr = get_scr_layer(screen, layer);
455 32380544 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
456 772452989 }
457
458 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
459 // Coordinates are clamped to the world bounds.
460 3478162903 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
461 {
462 3478162903 x = std::clamp(x, 0, world_w - 1);
463 3478162903 y = std::clamp(y, 0, world_h - 1);
464
465 DCHECK_LAYER_ZERO_INDEX(layer);
466
2/2
✓ Branch 0 taken 3450425731 times.
✓ Branch 1 taken 27737172 times.
3478162903 if (!is_in_scrolling_region())
467 {
468 3450425731 int pos = COMBOPOS(x, y);
469 3450425731 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
470 }
471 27737172 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
472 3478162903 }
473
474 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
475 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
476 {
477 DCHECK_LAYER_ZERO_INDEX(layer);
478 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
479 }
480
481 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
482 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
483 62061 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
484 {
485 DCHECK_LAYER_ZERO_INDEX(layer);
486 62061 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
487 }
488
489 25041433 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
490 {
491 DCHECK_LAYER_ZERO_INDEX(layer);
492 25041433 rpos_handle.layer = layer;
493 25041433 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
494 25041433 }
495
496 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
497 // Coordinates are clamped to the world bounds.
498 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
499 {
500 DCHECK_LAYER_ZERO_INDEX(layer);
501
502 52808 x = std::clamp(x, 0, world_w - 1);
503 52808 y = std::clamp(y, 0, world_h - 1);
504
505 52808 auto maybe_ffc_handle = getFFCAt(x, y);
506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
507 return maybe_ffc_handle.value();
508
509 52808 auto rpos = COMBOPOS_REGION_B(x, y);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
511 return rpos_handle_t();
512 52808 return get_rpos_handle(rpos, layer);
513 52808 }
514
515 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
516 // directly or via zscript) only last until the next area is loaded (via loadscr).
517
518 // Returns the screen containing the (x, y) world position.
519 1626783942 mapscr* get_scr_for_world_xy(int x, int y)
520 {
521 // Quick path, but should work the same without.
522
2/2
✓ Branch 0 taken 1615650942 times.
✓ Branch 1 taken 11133000 times.
1626783942 if (!is_in_scrolling_region()) return origin_scr;
523 11133000 return get_scr(get_screen_for_world_xy(x, y));
524 1626783942 }
525
526 24447223 mapscr* get_scr_for_rpos(rpos_t rpos)
527 {
528 // Quick path, but should work the same without.
529
2/2
✓ Branch 0 taken 24309277 times.
✓ Branch 1 taken 137946 times.
24447223 if (!is_in_scrolling_region()) return origin_scr;
530 137946 return get_scr(get_screen_for_rpos(rpos));
531 24447223 }
532
533 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
534 {
535 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
536 }
537
538 // Note: layer=0 is the base screen, 1 is the first layer, etc.
539 2298105711 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
540 {
541 DCHECK_LAYER_ZERO_INDEX(layer);
542
2/2
✓ Branch 0 taken 2286685713 times.
✓ Branch 1 taken 11419998 times.
2298105711 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
543
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 10711064 times.
11419998 return layer == 0 ?
544 708934 get_scr_for_world_xy(x, y) :
545 10711064 get_scr_layer(get_screen_for_world_xy(x, y), layer);
546 2298105711 }
547
548 1826591771 int get_region_screen_offset(int screen)
549 {
550 1826591771 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
551 }
552
553 654676685 int get_screen_for_region_index_offset(int offset)
554 {
555 654676685 int scr_dx = offset % cur_region.screen_width;
556 654676685 int scr_dy = offset / cur_region.screen_width;
557 654676685 int screen = cur_screen + scr_dx + scr_dy*16;
558 654676685 return screen;
559 }
560
561 654492848 mapscr* get_scr_for_region_index_offset(int offset)
562 {
563 654492848 int screen = get_screen_for_region_index_offset(offset);
564 654492848 return get_scr(screen);
565 }
566
567 // The screen at (map, screen) must exist.
568 1419640281 mapscr* get_scr(int map, int screen)
569 {
570 1419640281 mapscr* scr = get_scr_maybe(map, screen);
571
1/2
✓ Branch 0 taken 1419640281 times.
✗ Branch 1 not taken.
1419640281 CHECK(scr);
572 1419640281 return scr;
573 }
574
575 836962806 mapscr* get_scr(int screen)
576 {
577 836962806 return get_scr(cur_map, screen);
578 }
579
580 // Returns null if active screen does not exist.
581 1449184912 mapscr* get_scr_maybe(int map, int screen)
582 {
583 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
584
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1449184912 times.
1449184912 if (map == cur_map)
586 {
587
2/2
✓ Branch 0 taken 1428409976 times.
✓ Branch 1 taken 20774936 times.
1449184912 if (screen == cur_screen)
588 1428409976 return origin_scr;
589
590 20774936 int index = screen*7;
591
2/2
✓ Branch 0 taken 20763846 times.
✓ Branch 1 taken 11090 times.
20774936 if (temporary_screens[index])
592 20763846 return temporary_screens[index];
593
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (screen == home_screen)
595 return special_warp_return_scr;
596 11090 }
597
598
3/6
✓ Branch 0 taken 11090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11090 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
599 {
600 11090 int index = screen*7;
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
602 11090 return FFCore.ScrollingScreensAll[index];
603 }
604
605 return nullptr;
606 1449184912 }
607
608 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
609 7024982816 mapscr* get_scr_layer(int map, int screen, int layer)
610 {
611 DCHECK_LAYER_ZERO_INDEX(layer);
612
2/2
✓ Branch 0 taken 6444797769 times.
✓ Branch 1 taken 580185047 times.
7024982816 if (layer == 0)
613 580185047 return get_scr(map, screen);
614
615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6444797769 times.
6444797769 if (map == cur_map)
616 {
617 6444797769 int index = screen*7 + layer;
618
2/2
✓ Branch 0 taken 6444729369 times.
✓ Branch 1 taken 68400 times.
6444797769 if (temporary_screens[index])
619 6444729369 return temporary_screens[index];
620
621
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
622 1860 return &special_warp_return_scrs[layer];
623 66540 }
624
625
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
626 {
627 66540 int index = screen*7 + layer;
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
629 66540 return FFCore.ScrollingScreensAll[index];
630 }
631
632 NOTREACHED();
633 7024982816 }
634
635 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
636 6627644796 mapscr* get_scr_layer(int screen, int layer)
637 {
638 6627644796 return get_scr_layer(cur_map, screen, layer);
639 }
640
641 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
642 // Return nullptr if screen is not valid.
643 395265111 mapscr* get_scr_layer_valid(int screen, int layer)
644 {
645
2/2
✓ Branch 0 taken 77591140 times.
✓ Branch 1 taken 317673971 times.
395265111 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
646 77591140 return scr;
647 317673971 return nullptr;
648 395265111 }
649
650 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
651 {
652 401 int x = get_region_relative_dx(screen);
653 401 int y = get_region_relative_dy(screen);
654
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
655 71 return nullptr;
656
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
657 return nullptr;
658
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
659 return nullptr;
660
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
661 189 return nullptr;
662
663 141 screen = screen_index_direction(screen, dir);
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
665 return get_scr(screen);
666
667 141 return nullptr;
668 401 }
669
670 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
671 {
672 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
673 183837 uint8_t i = id % MAXFFCS;
674 183837 mapscr* scr = get_scr(screen);
675 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
676 183837 return {scr, screen, id, i, ffc};
677 }
678
679 34354 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
680 {
681 34354 x += get_region_relative_dx(screen) * 256;
682 34354 y += get_region_relative_dy(screen) * 176;
683 34354 return {x, y};
684 }
685
686 1048513 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
687 {
688 1048513 int x = get_region_relative_dx(screen) * 256;
689 1048513 int y = get_region_relative_dy(screen) * 176;
690 1048513 return {x, y};
691 }
692
693 12056251919 int32_t COMBOPOS(int32_t x, int32_t y)
694 {
695 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
696 12056251919 return (y & 0xF0) + (x >> 4);
697 }
698 int32_t COMBOPOS_B(int32_t x, int32_t y)
699 {
700 if(unsigned(x) >= 256 || unsigned(y) >= 176)
701 return -1;
702 return (y & 0xF0) + (x >> 4);
703 }
704 3299922833 int32_t COMBOX(int32_t pos)
705 {
706 3299922833 return pos % 16 * 16;
707 }
708 3299922833 int32_t COMBOY(int32_t pos)
709 {
710 3299922833 return pos & 0xF0;
711 }
712
713 112331329 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
714 {
715
2/2
✓ Branch 0 taken 83778683 times.
✓ Branch 1 taken 28552646 times.
112331329 if (!is_in_scrolling_region())
716 83778683 return (rpos_t) COMBOPOS(x, y);
717
718 DCHECK(is_in_world_bounds(x, y));
719 28552646 int scr_dx = x / (16*16);
720 28552646 int scr_dy = y / (11*16);
721 28552646 int pos = COMBOPOS(x%256, y%176);
722 28552646 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
723 112331329 }
724 6258532123 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
725 {
726
2/2
✓ Branch 0 taken 1387699 times.
✓ Branch 1 taken 6257144424 times.
6258532123 if (!is_in_world_bounds(x, y))
727 1387699 return rpos_t::None;
728
729 6257144424 int scr_dx = x / (16*16);
730 6257144424 int scr_dy = y / (11*16);
731 6257144424 int pos = COMBOPOS(x%256, y%176);
732 6257144424 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 6258532123 }
734 25175100 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
735 {
736 25175100 int scr_index = static_cast<int32_t>(rpos) / 176;
737 25175100 int scr_dx = scr_index % cur_region.screen_width;
738 25175100 int scr_dy = scr_index / cur_region.screen_width;
739 25175100 int pos = RPOS_TO_POS(rpos);
740 25175100 int x = scr_dx*16*16 + COMBOX(pos);
741 25175100 int y = scr_dy*11*16 + COMBOY(pos);
742 25175100 return {x, y};
743 }
744 60396 int32_t COMBOX_REGION(rpos_t rpos)
745 {
746 60396 auto [x, y] = COMBOXY_REGION(rpos);
747 60396 return x;
748 }
749 12225 int32_t COMBOY_REGION(rpos_t rpos)
750 {
751 12225 auto [x, y] = COMBOXY_REGION(rpos);
752 12225 return y;
753 }
754
755 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
756 {
757 DCHECK(is_in_world_bounds(x, y));
758
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
759 70177 return (rpos_t)(x + y * 16);
760
761 int scr_dx = x / 16;
762 int scr_dy = y / 11;
763 x %= 16;
764 y %= 11;
765 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
766 70177 }
767 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
768 {
769 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
770 70632 int scr_dx = scr_index % cur_region.screen_width;
771 70632 int scr_dy = scr_index / cur_region.screen_width;
772 70632 int pos = RPOS_TO_POS(rpos);
773 70632 int x = scr_dx*16 + pos%16;
774 70632 int y = scr_dy*11 + pos/16;
775 70632 return {x, y};
776 }
777
778 88102053 int32_t mapind(int32_t map, int32_t scr)
779 {
780 88102053 return map * MAPSCRSNORMAL + scr;
781 }
782
783 FONT *get_zc_font(int index);
784
785 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
786 extern movingblock mblock2; //mblock[4]?
787 extern portal mirror_portal;
788
789 void Z_message_d(const char *format,...)
790 {
791 #ifdef _DEBUG
792 char buf[512];
793 va_list ap;
794 va_start(ap, format);
795 vsprintf(buf, format, ap);
796 va_end(ap);
797
798 al_trace("%s",buf);
799 #else
800 format=format;
801 #endif
802 }
803
804
805
806 bool checktrigger=false;
807
808 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
809 {
810 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
811 int32_t index = script_drawing_commands.GetNext();
812
813 if(index < 0)
814 return;
815
816 int32_t *sdci = &script_drawing_commands[index][0];
817
818 sdci[0] = RECTR;
819 sdci[1] = 30000;
820 sdci[2] = x1*10000;
821 sdci[3] = y1*10000;
822 sdci[4] = x2*10000;
823 sdci[5] = y2*10000;
824 sdci[6] = 10000;
825 sdci[7] = 10000;
826 sdci[8] = 0;
827 sdci[9] = 0;
828 sdci[10] = 0;
829 sdci[11] = 10000;
830 sdci[12] = 1280000;
831 }
832
833 void clear_dmap(word i)
834 {
835 DMaps[i].clear();
836 }
837
838 void clear_dmaps()
839 {
840 for(int32_t i=0; i<MAXDMAPS; i++)
841 {
842 clear_dmap(i);
843 }
844 }
845
846 222617341 int32_t isdungeon(int32_t dmap, int32_t screen)
847 {
848
2/2
✓ Branch 0 taken 222572190 times.
✓ Branch 1 taken 45151 times.
222617341 if (dmap < 0) dmap = cur_dmap;
849
850 // dungeons can have any dlevel above 0
851
2/2
✓ Branch 0 taken 122052752 times.
✓ Branch 1 taken 100564589 times.
222617341 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
852 {
853
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 100554628 times.
100564589 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
854 9961 return 0;
855
856 100554628 return 1;
857 }
858
859 // dlevels that aren't dungeons are caves
860
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122015925 times.
122052752 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
861 36827 return 1;
862
863 122015925 return 0;
864 222617341 }
865
866 39759422 int32_t isdungeon(int32_t screen)
867 {
868 39759422 return isdungeon(cur_dmap, screen);
869 }
870
871 182731898 int32_t isdungeon()
872 {
873 182731898 return isdungeon(cur_dmap, hero_screen);
874 }
875
876 88203 bool canPermSecret(int32_t dmap, int32_t screen)
877 {
878
2/2
✓ Branch 0 taken 13767 times.
✓ Branch 1 taken 74436 times.
88203 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
879 }
880
881 1369419839 int32_t MAPCOMBO(int32_t x, int32_t y)
882 {
883 1369419839 x = vbound(x, 0, world_w-1);
884 1369419839 y = vbound(y, 0, world_h-1);
885 1369419839 int pos = COMBOPOS(x%256, y%176);
886 1369419839 mapscr* scr = get_scr_for_world_xy(x, y);
887 1369419839 return scr->data[pos];
888 }
889
890 //specific layers 1 to 6
891 1701221748 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
892 {
893 DCHECK(layer >= 1 && layer <= 6);
894
3/4
✓ Branch 0 taken 1680885222 times.
✓ Branch 1 taken 20336526 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1680885222 times.
1701221748 if (!is_in_world_bounds(x, y) || layer <= 0)
895 20336526 return 0;
896
897 1680885222 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
898
2/2
✓ Branch 0 taken 491264524 times.
✓ Branch 1 taken 1189620698 times.
1680885222 if (!m->is_valid())
899 1189620698 return 0;
900
901 491264524 int pos = COMBOPOS(x%256, y%176);
902 491264524 return m->data[pos];
903 1701221748 }
904
905 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
906 {
907 DCHECK(layer >= 1 && layer <= 6);
908 if (!is_in_world_bounds(x, y) || layer <= 0)
909 return 0;
910
911 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
912 if (!m->is_valid())
913 return 0;
914
915 int pos = COMBOPOS(x%256, y%176);
916 return m->cset[pos];
917 }
918
919 189308 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
920 {
921 DCHECK(layer >= 1 && layer <= 6);
922
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
923 return 0;
924
925 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
926
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
927 40394 return 0;
928
929 148914 int pos = COMBOPOS(x%256, y%176);
930 148914 return m->sflag[pos];
931 189308 }
932
933 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
934 {
935 DCHECK(layer >= 1 && layer <= 6);
936
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
937 return 0;
938
939 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
940
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 472 times.
6281 if (!m->is_valid())
941 472 return 0;
942
943 5809 int pos = COMBOPOS(x%256, y%176);
944 5809 return combobuf[m->data[pos]].type;
945 6281 }
946
947 189308 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
948 {
949 DCHECK(layer >= 1 && layer <= 6);
950
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
951 return 0;
952
953 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
954
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
955 40394 return 0;
956
957 148914 int pos = COMBOPOS(x%256, y%176);
958 148914 return combobuf[m->data[pos]].flag;
959 189308 }
960
961
962 // True if the FFC covers x, y and is not ethereal or a changer.
963 2465108684 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
964 {
965
2/2
✓ Branch 0 taken 744299894 times.
✓ Branch 1 taken 1720808790 times.
2465108684 if (ffc_handle.data()<=0)
966 744299894 return false;
967
968
2/2
✓ Branch 0 taken 300884500 times.
✓ Branch 1 taken 1419924290 times.
1720808790 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
969 300884500 return false;
970
971 1419924290 int32_t fx=ffc_handle.ffc->x.getInt();
972
4/4
✓ Branch 0 taken 976336641 times.
✓ Branch 1 taken 443587649 times.
✓ Branch 2 taken 866205573 times.
✓ Branch 3 taken 110131068 times.
1419924290 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
973 1309793222 return false;
974
975 110131068 int32_t fy=ffc_handle.ffc->y.getInt();
976
4/4
✓ Branch 0 taken 80147059 times.
✓ Branch 1 taken 29984009 times.
✓ Branch 2 taken 60079259 times.
✓ Branch 3 taken 20067800 times.
110131068 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
977 90063268 return false;
978
979 20067800 return true;
980 2465108684 }
981
982 994192450 int32_t MAPFFCOMBO(int32_t x,int32_t y)
983 {
984
2/2
✓ Branch 0 taken 13163663 times.
✓ Branch 1 taken 981028787 times.
994192450 if (auto ffc_handle = getFFCAt(x, y))
985 13163663 return ffc_handle->data();
986 981028787 return 0;
987 994192450 }
988
989 206464 int32_t MAPCSET(int32_t x, int32_t y)
990 {
991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 206464 times.
206464 if (!is_in_world_bounds(x, y))
992 return 0;
993 206464 mapscr* scr = get_scr_for_world_xy(x, y);
994 206464 int pos = COMBOPOS(x%256, y%176);
995 206464 return scr->cset[pos];
996 206464 }
997
998 73441316 int32_t MAPFLAG(int32_t x, int32_t y)
999 {
1000
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73413176 times.
73441316 if (!is_in_world_bounds(x, y))
1001 28140 return 0;
1002 73413176 mapscr* scr = get_scr_for_world_xy(x, y);
1003 73413176 int pos = COMBOPOS(x%256, y%176);
1004 73413176 return scr->sflag[pos];
1005 73441316 }
1006
1007 162498725 int32_t COMBOTYPE(int32_t x,int32_t y)
1008 {
1009 162498725 int32_t b=1;
1010
2/2
✓ Branch 0 taken 94851328 times.
✓ Branch 1 taken 67647397 times.
162498725 if(x&8) b<<=2;
1011
2/2
✓ Branch 0 taken 81238616 times.
✓ Branch 1 taken 81260109 times.
162498725 if(y&8) b<<=1;
1012
1013
2/2
✓ Branch 0 taken 324990412 times.
✓ Branch 1 taken 162491426 times.
487481838 for (int32_t i = 0; i <= 1; ++i)
1014 {
1015
2/2
✓ Branch 0 taken 314657464 times.
✓ Branch 1 taken 10332948 times.
324990412 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1016 {
1017
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 314657464 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
314657464 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1018 314657464 }
1019 else
1020 {
1021
4/4
✓ Branch 0 taken 10451 times.
✓ Branch 1 taken 10322497 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7299 times.
10332948 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1022 }
1023 324983113 }
1024
1025 162491426 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1026
5/6
✓ Branch 0 taken 3578958 times.
✓ Branch 1 taken 158912468 times.
✓ Branch 2 taken 3019272 times.
✓ Branch 3 taken 559686 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3019272 times.
162491426 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1027 {
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3019272 times.
3019272 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3019272 times.
3019272 if(cmb.usrflags&cflag3) return cNONE;
1030 3019272 }
1031 162491426 return cmb.type;
1032 162498725 }
1033
1034 50039270 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1035 {
1036 50039270 return combobuf[MAPFFCOMBO(x,y)].type;
1037 }
1038
1039 4954581 int32_t FFORCOMBO(int32_t x, int32_t y)
1040 {
1041
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4896065 times.
4954581 if (auto ffc_handle = getFFCAt(x, y))
1042 58516 return ffc_handle->data();
1043
1044 4896065 return MAPCOMBO(x,y);
1045 4954581 }
1046
1047 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1048 {
1049 for (int32_t i = 0; i <= 1; ++i)
1050 {
1051 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1052 {
1053 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1054 }
1055 else
1056 {
1057 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1058 }
1059 }
1060 int32_t b=1;
1061
1062 if(x&8) b<<=2;
1063
1064 if(y&8) b<<=1;
1065 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1066 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1067 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1068 return cmb.type;
1069 }
1070
1071 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1072 {
1073 if (auto ffc_handle = getFFCAt(x, y))
1074 return ffc_handle->data();
1075
1076 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1077 }
1078
1079 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1080 {
1081 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1082 }
1083
1084 69940888 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1085 {
1086
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 69913036 times.
69940888 if (!is_in_world_bounds(x, y))
1087 27852 return 0;
1088
1089 69913036 mapscr* scr = get_scr_for_world_xy(x, y);
1090 69913036 int pos = COMBOPOS(x%256, y%176);
1091 69913036 return combobuf[scr->data[pos]].flag;
1092 69940888 }
1093
1094 56672576 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 55926399 times.
56672576 if (auto ffc_handle = getFFCAt(x, y))
1097 746177 return ffc_handle->cflag();
1098
1099 55926399 return 0;
1100 56672576 }
1101
1102 1307344419 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1103 {
1104 2783147795 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1105 1475803376 return ffcIsAt(ffc_handle, x, y);
1106 });
1107 }
1108
1109 3039 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1110 {
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3039 times.
3039 if (!rpos_handle.scr->is_valid()) return 0;
1112 3039 return rpos_handle.data();
1113 3039 }
1114
1115 3148252241 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1116 {
1117 DCHECK_LAYER_NEG1_INDEX(layer);
1118
2/2
✓ Branch 0 taken 22331328 times.
✓ Branch 1 taken 3125920913 times.
3148252241 if (!is_in_world_bounds(x, y)) return 0;
1119
2/2
✓ Branch 0 taken 3054479462 times.
✓ Branch 1 taken 71441451 times.
3125920913 if (layer == -1) return MAPCOMBO(x, y);
1120
1121 3054479462 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1122
2/2
✓ Branch 0 taken 2107551740 times.
✓ Branch 1 taken 946927722 times.
3054479462 if (!rpos_handle.scr->is_valid()) return 0;
1123
1124 946927722 return rpos_handle.data();
1125 3148252241 }
1126
1127 17263280 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1128 {
1129 17263280 auto cid = handle.data();
1130 17263280 auto* cmb = &handle.combo();
1131 17263280 bool done = false;
1132 17263280 std::set<int32_t> visited;
1133
2/2
✓ Branch 0 taken 17263280 times.
✓ Branch 1 taken 17263280 times.
34526560 while(!done)
1134 {
1135
2/4
✓ Branch 0 taken 17263280 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17263280 times.
17263280 if(visited.contains(cid))
1136 {
1137 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1138 break; // prevent infinite loop
1139 }
1140
1/2
✓ Branch 0 taken 17263280 times.
✗ Branch 1 not taken.
17263280 visited.insert(cid);
1141
1142 17263280 done = true; // don't loop again unless something changes
1143
1/2
✓ Branch 0 taken 17263280 times.
✗ Branch 1 not taken.
17855235 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1144 591955 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1145 });
1146
2/4
✓ Branch 0 taken 17263280 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17263280 times.
17263280 if(handle.data() != cid)
1147 {
1148 cid = handle.data();
1149 cmb = &handle.combo();
1150 done = false; // loop again for the new combo
1151 }
1152 }
1153 17263280 }
1154 51577 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1155 {
1156 51577 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1157 51577 }
1158 34629 void handle_region_load_trigger()
1159 {
1160
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 34477 times.
34629 if (is_in_scrolling_region())
1161 {
1162
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1163 {
1164
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1165 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1166 19456 }
1167 152 }
1168 34477 else handle_screen_load_trigger(create_screen_handles_one(get_scr(hero_screen)));
1169 34629 }
1170
1171 15800 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1172 {
1173 15800 auto screen_handles = create_screen_handles_one(&scr);
1174
1175
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 15261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15800 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1176 {
1177 539 reveal_hidden_stairs(&scr, screen, false);
1178 539 bool do_layers = false;
1179 539 bool from_active_screen = false;
1180 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1181 539 }
1182
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if (flags & mLIGHTBEAM)
1183 {
1184 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1185 if (rpos_handle.ctype() == cLIGHTTARGET)
1186 {
1187 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1188 rpos_handle.increment_data();
1189 }
1190 });
1191 }
1192
1193 15800 int lvl = DMaps[cur_dmap].level;
1194 15800 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1195 15800 toggle_gswitches_load(screen_handles);
1196
1197
2/2
✓ Branch 0 taken 15708 times.
✓ Branch 1 taken 92 times.
15800 if(flags&mLOCKBLOCK) // if special stuff done before
1198 {
1199 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1200 92 }
1201
1202
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1203 {
1204 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1205 }
1206
1207
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1208 {
1209 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1210 }
1211
1212
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1213 {
1214 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1215 }
1216
1217
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSCHEST) // if special stuff done before
1218 {
1219 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1220 }
1221
1222
1223 15800 int mi = mapind(map, screen);
1224 15800 clear_xdoors_mi(screen_handles, mi);
1225 15800 clear_xstatecombos_mi(screen_handles, mi);
1226
1227 15800 handle_screen_load_trigger(screen_handles);
1228 15800 }
1229
1230 53194 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1231 {
1232
2/4
✓ Branch 0 taken 53194 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53194 times.
53194 if (map < 0 || screen < 0)
1233 return std::nullopt;
1234
1235 53194 const mapscr* source = get_canonical_scr(map, screen);
1236
2/2
✓ Branch 0 taken 40960 times.
✓ Branch 1 taken 12234 times.
53194 if (!source->is_valid())
1237 12234 return std::nullopt;
1238
1239
2/2
✓ Branch 0 taken 8308 times.
✓ Branch 1 taken 32652 times.
40960 if (layer >= 0)
1240 {
1241
2/2
✓ Branch 0 taken 25160 times.
✓ Branch 1 taken 7492 times.
32652 if (source->layermap[layer] <= 0)
1242 25160 return std::nullopt;
1243
1244 7492 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1245
1/2
✓ Branch 0 taken 7492 times.
✗ Branch 1 not taken.
7492 if (!source->is_valid())
1246 return std::nullopt;
1247 7492 }
1248
1249
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1250 15800 mapscr scr = *source;
1251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15800 times.
15800 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1252
1253 15800 return scr;
1254 53194 }
1255
1256 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1257 {
1258
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1259
1260
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1261 return 0;
1262
1263 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1264 // `apply_state_changes_to_screen` checks).
1265
4/5
✓ Branch 0 taken 4976 times.
✓ Branch 1 taken 22227 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4976 times.
✓ Branch 4 taken 22227 times.
32179 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1266 4976 return s->data[pos];
1267
1268 22227 return 0;
1269 27203 }
1270
1271 // Read from the current temporary screens or, if (map, screen) is not loaded,
1272 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1273 137736708 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1274 {
1275 DCHECK_LAYER_NEG1_INDEX(layer);
1276 DCHECK(map >= 0 && screen >= 0);
1277
1278
2/2
✓ Branch 0 taken 137709505 times.
✓ Branch 1 taken 27203 times.
137736708 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1279
1280 // Screen is not in the current region, so we have to load and trigger some secrets.
1281 27203 int pos = COMBOPOS(x, y);
1282 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1283 137736708 }
1284
1285 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1286 {
1287 DCHECK_LAYER_NEG1_INDEX(layer);
1288 DCHECK(map >= 0 && screen >= 0);
1289 DCHECK(is_valid_rpos(rpos));
1290
1291 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1292
1293 // Screen is not currently loaded, so we have to load and trigger some secrets.
1294 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1295 }
1296
1297 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1298 {
1299 DCHECK_LAYER_NEG1_INDEX(layer);
1300 if (!is_in_world_bounds(x, y))
1301 return 0;
1302 if (layer == -1) return MAPCSET(x, y);
1303
1304 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1305 if (!rpos_handle.scr->is_valid()) return 0;
1306
1307 return rpos_handle.cset();
1308 }
1309
1310 98644677 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1311 {
1312 DCHECK_LAYER_NEG1_INDEX(layer);
1313
3/4
✓ Branch 0 taken 1894252 times.
✓ Branch 1 taken 96750425 times.
✓ Branch 2 taken 1894252 times.
✗ Branch 3 not taken.
98644677 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1314 return 0;
1315
2/2
✓ Branch 0 taken 81082879 times.
✓ Branch 1 taken 17561798 times.
98644677 if (layer == -1) return MAPFLAG(x, y);
1316
1317 81082879 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1318
2/2
✓ Branch 0 taken 62870783 times.
✓ Branch 1 taken 18212096 times.
81082879 if (!rpos_handle.scr->is_valid()) return 0;
1319
1320 18212096 return rpos_handle.sflag();
1321 98644677 }
1322
1323 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1324 {
1325 if(layer < 1)
1326 {
1327 for (int32_t i = layer+1; i <= 1; ++i)
1328 {
1329 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1330 {
1331 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1332 }
1333 else
1334 {
1335 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1336 }
1337 }
1338 }
1339 if(layer==-1) return COMBOTYPE(x,y);
1340
1341 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1342 if (!rpos_handle.scr->is_valid()) return 0;
1343
1344 return rpos_handle.ctype();
1345 }
1346
1347 // Returns the flag for the combo at the given position.
1348 // This is also known as an "inherent flag".
1349 96877834 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1350 {
1351 DCHECK_LAYER_NEG1_INDEX(layer);
1352
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 96877546 times.
96877834 if (!is_in_world_bounds(x, y))
1353 288 return 0;
1354
2/2
✓ Branch 0 taken 81024228 times.
✓ Branch 1 taken 15853318 times.
96877546 if (layer == -1) return MAPCOMBOFLAG(x, y);
1355
1356 81024228 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1357
2/2
✓ Branch 0 taken 62880627 times.
✓ Branch 1 taken 18143601 times.
81024228 if (!rpos_handle.scr->is_valid()) return 0;
1358
1359 18143601 return rpos_handle.cflag();
1360 96877834 }
1361
1362 11626863 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1363 {
1364 DCHECK_LAYER_ZERO_INDEX(layer);
1365 11626863 auto rpos_handle = get_rpos_handle(rpos, layer);
1366
2/2
✓ Branch 0 taken 6436480 times.
✓ Branch 1 taken 5190383 times.
11626863 if (!rpos_handle.scr->is_valid()) return false;
1367
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5185818 times.
5190383 if (rpos_handle.sflag() == flag) return true;
1368
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 5148113 times.
5185818 if (rpos_handle.cflag() == flag) return true;
1369 5148113 return false;
1370 11626863 }
1371
1372 1697065 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1373 {
1374 DCHECK(is_valid_rpos(rpos));
1375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1697065 times.
1697065 if (rpos > region_max_rpos) return false;
1376
1377
2/2
✓ Branch 0 taken 11626863 times.
✓ Branch 1 taken 1654795 times.
13281658 for(auto q = 0; q < 7; ++q)
1378 {
1379
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11584593 times.
11626863 if(HASFLAG(flag, q, rpos))
1380 42270 return true;
1381 11584593 }
1382 1654795 return false;
1383 1697065 }
1384
1385 const char *screenstate_string[32] =
1386 {
1387 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1388 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1389 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1390 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1391 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1392 };
1393
1394 34666 void eventlog_mapflags()
1395 {
1396 34666 std::ostringstream oss;
1397
1398 34666 int mi = mapind(cur_map, home_screen);
1399
1/2
✓ Branch 0 taken 34666 times.
✗ Branch 1 not taken.
34666 dword g = game->maps[mi];
1400
1401
2/4
✓ Branch 0 taken 34666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34666 times.
✗ Branch 3 not taken.
34666 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1402
2/2
✓ Branch 0 taken 14434 times.
✓ Branch 1 taken 20232 times.
34666 if(g) // Main States
1403 {
1404 static const int order[] =
1405 {
1406 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1407 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1408 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1409 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1410 };
1411
1412
1/2
✓ Branch 0 taken 14434 times.
✗ Branch 1 not taken.
14434 oss << " [";
1413 14434 bool comma = false;
1414
2/2
✓ Branch 0 taken 14434 times.
✓ Branch 1 taken 230944 times.
245378 for(int fl : order)
1415 {
1416
2/2
✓ Branch 0 taken 8934 times.
✓ Branch 1 taken 222010 times.
230944 if(!(g&fl))
1417 222010 continue;
1418 8934 byte ind = byte(log2(double(fl)));
1419
2/2
✓ Branch 0 taken 1916 times.
✓ Branch 1 taken 7018 times.
8934 if(comma)
1420
1/2
✓ Branch 0 taken 1916 times.
✗ Branch 1 not taken.
1916 oss << ", ";
1421
1/2
✓ Branch 0 taken 8934 times.
✗ Branch 1 not taken.
8934 oss << screenstate_string[ind];
1422 8934 comma = true;
1423 }
1424
1/2
✓ Branch 0 taken 14434 times.
✗ Branch 1 not taken.
14434 oss << "]";
1425 14434 }
1426
3/4
✓ Branch 0 taken 34666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 34628 times.
34666 if(game->xstates[mi]) // ExStates
1427 {
1428
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << " Ex[";
1429 38 bool comma = false;
1430
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1216 times.
1254 for(byte fl = 0; fl < 32; ++fl)
1431 {
1432
3/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1172 times.
1216 if(game->xstates[mi] & (1<<fl))
1433 {
1434
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 38 times.
44 if(comma)
1435
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 oss << ", ";
1436
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 oss << int(fl);
1437 44 comma = true;
1438 44 }
1439 1216 }
1440
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << "]";
1441 38 }
1442 { // ExDoors
1443
2/2
✓ Branch 0 taken 34666 times.
✓ Branch 1 taken 138664 times.
173330 for(int q = 0; q < 4; ++q)
1444 {
1445 138664 bool comma = false;
1446
3/4
✓ Branch 0 taken 138664 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 138662 times.
✓ Branch 3 taken 2 times.
138664 if(auto v = game->xdoors[mi][q])
1447 {
1448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1449 oss << ",";
1450
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1451
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1452
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1453
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1454
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1455
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1456 2 comma = true;
1457 2 }
1458 138664 }
1459 }
1460
2/4
✓ Branch 0 taken 34666 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34666 times.
34666 Z_eventlog("%s\n", oss.str().c_str());
1461 34666 }
1462
1463 // set specific flag
1464 5600 void setmapflag(mapscr* scr, uint32_t flag)
1465 {
1466
2/2
✓ Branch 0 taken 5587 times.
✓ Branch 1 taken 13 times.
5600 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1467 5600 int mi = mapind(cur_map, scr->screen);
1468 5600 setmapflag_mi(scr, mi, flag);
1469 5600 }
1470 57 void setmapflag_homescr(uint32_t flag)
1471 {
1472 57 int mi = mapind(cur_map, home_screen);
1473 57 setmapflag_mi(origin_scr, mi, flag);
1474 57 }
1475 2022 void setmapflag_mi(int32_t mi, uint32_t flag)
1476 {
1477 2022 byte cscr = mi&((1<<7)-1);
1478 2022 byte cmap = (mi>>7);
1479 2022 mapscr* scr = origin_scr;
1480
2/2
✓ Branch 0 taken 833 times.
✓ Branch 1 taken 1189 times.
2022 if (is_in_current_region(cmap, cscr))
1481 1189 scr = get_scr(cmap, cscr);
1482
1483 2022 setmapflag_mi(scr, mi, flag);
1484 2022 }
1485
1486 8461 static void log_state_change(int map, int screen, std::string action)
1487 {
1488
6/6
✓ Branch 0 taken 1911 times.
✓ Branch 1 taken 6550 times.
✓ Branch 2 taken 994 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 351 times.
✓ Branch 5 taken 643 times.
8461 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1489 6901 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1490 else
1491 1560 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1492 8461 }
1493
1494 7679 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1495 {
1496 7679 byte cscr = mi&((1<<7)-1);
1497 7679 byte cmap = (mi>>7);
1498
1499 7679 double temp=log2((double)flag);
1500
1/2
✓ Branch 0 taken 7679 times.
✗ Branch 1 not taken.
7679 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1501 7679 const char* replay_state_string = state_string;
1502
2/2
✓ Branch 0 taken 7161 times.
✓ Branch 1 taken 518 times.
7679 if(temp == 6) replay_state_string = "No Return";
1503
1504
3/4
✓ Branch 0 taken 7679 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6127 times.
7679 if (replay_is_active() && !(game->maps[mi] & flag))
1505
1/2
✓ Branch 0 taken 6127 times.
✗ Branch 1 not taken.
6127 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1506 7679 game->maps[mi] |= flag;
1507
1/2
✓ Branch 0 taken 7679 times.
✗ Branch 1 not taken.
7679 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1508
1509
2/2
✓ Branch 0 taken 2503 times.
✓ Branch 1 taken 5176 times.
7679 if((scr->nocarry&flag)!=flag)
1510 {
1511 5176 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1512 5176 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1513
1514 5176 std::vector<int32_t> done;
1515
2/2
✓ Branch 0 taken 5081 times.
✓ Branch 1 taken 95 times.
5176 bool looped = (nmap==cmap+1 && nscr==cscr);
1516
1517
6/6
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 5134 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 364 times.
✓ Branch 4 taken 364 times.
✓ Branch 5 taken 5176 times.
5540 while((nmap!=0) && !looped && !(nscr>=128))
1518 {
1519
3/4
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 171 times.
✓ Branch 3 taken 193 times.
364 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1520 {
1521
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1522
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1523
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1524
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1525 193 }
1526
1527 364 cmap=nmap;
1528 364 cscr=nscr;
1529 364 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1530 364 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1531
1532
2/2
✓ Branch 0 taken 889 times.
✓ Branch 1 taken 364 times.
1253 for(auto it = done.begin(); it != done.end(); it++)
1533 {
1534
2/2
✓ Branch 0 taken 847 times.
✓ Branch 1 taken 42 times.
889 if(*it == ((nmap-1)<<7)+nscr)
1535 42 looped = true;
1536 889 }
1537
1538
1/2
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
364 done.push_back(((nmap-1)<<7)+nscr);
1539 }
1540 5176 }
1541 7679 }
1542
1543 void unsetmapflag_home(uint32_t flag, bool anyflag)
1544 {
1545 int mi = mapind(cur_map, home_screen);
1546 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1547 }
1548
1549 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1550 {
1551 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1552 int mi = mapind(cur_map, scr->screen);
1553 unsetmapflag_mi(scr, mi, flag, anyflag);
1554 }
1555
1556 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1557 {
1558 471 byte cscr = mi&((1<<7)-1);
1559 471 byte cmap = (mi>>7);
1560 471 mapscr* scr = origin_scr;
1561
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1562 11 scr = get_scr(cmap, cscr);
1563
1564 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1565 471 }
1566
1567 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1568 {
1569 471 byte cscr = mi&((1<<7)-1);
1570 471 byte cmap = (mi>>7);
1571
1572
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1573 460 game->maps[mi] &= ~flag;
1574
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1575 {
1576 if(!(scr->flags4&fNOITEMRESET))
1577 game->maps[mi] &= ~flag;
1578 }
1579 11 else game->maps[mi] &= ~flag;
1580
1581 471 double temp=log2((double)flag);
1582
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1583
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1584
1585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1586 {
1587 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1588 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1589
1590 471 std::vector<int32_t> done;
1591
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1592
1593
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1594 {
1595
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1596 {
1597
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1598
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1599 72 }
1600
1601 84 cmap=nmap;
1602 84 cscr=nscr;
1603 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1604 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1605
1606
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1607 {
1608
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1609 6 looped = true;
1610 546 }
1611
1612
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1613 }
1614 471 }
1615 471 }
1616
1617 49920091 bool getmapflag(int32_t screen, uint32_t flag)
1618 {
1619
2/2
✓ Branch 0 taken 1342356 times.
✓ Branch 1 taken 48577735 times.
49920091 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1620 49920091 return (game->maps[mi] & flag) != 0;
1621 }
1622 6192011 bool getmapflag(mapscr* scr, uint32_t flag)
1623 {
1624 6192011 return getmapflag(scr->screen, flag);
1625 }
1626
1627 60 void setxmapflag(int32_t screen, uint32_t flag)
1628 {
1629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1630 60 setxmapflag_mi(mi, flag);
1631 60 }
1632 62 void setxmapflag_mi(int32_t mi, uint32_t flag)
1633 {
1634
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 41 times.
62 if(game->xstates[mi] & flag) return;
1635 41 byte cscr = mi&((1<<7)-1);
1636 41 byte cmap = (mi>>7);
1637
1638 41 byte temp=(byte)log2((double)flag);
1639
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1640
1641 41 game->xstates[mi] |= flag;
1642
1643 41 mapscr* scr = origin_scr;
1644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (is_in_current_region(cmap, cscr))
1645 41 scr = get_scr(cmap, cscr);
1646
1647
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 if((scr->exstate_carry&flag)==flag)
1648 {
1649 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1650 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1651
1652 std::vector<int32_t> done;
1653 bool looped = (nmap==cmap+1 && nscr==cscr);
1654
1655 while((nmap!=0) && !looped && !(nscr>=128))
1656 {
1657 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1658 {
1659 log_state_change(nmap, nscr, "ExState change carried over");
1660 if (replay_is_active())
1661 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1662 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1663 }
1664
1665 cmap=nmap;
1666 cscr=nscr;
1667 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1668 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1669
1670 for(auto it = done.begin(); it != done.end(); it++)
1671 {
1672 if(*it == ((nmap-1)<<7)+nscr)
1673 looped = true;
1674 }
1675
1676 done.push_back(((nmap-1)<<7)+nscr);
1677 }
1678 }
1679 62 }
1680 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1681 {
1682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1683 2 unsetxmapflag_mi(mi, flag);
1684 2 }
1685 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1686 {
1687
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1688 1 byte cscr = mi&((1<<7)-1);
1689 1 byte cmap = (mi>>7);
1690 1 byte temp=(byte)log2((double)flag);
1691
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1692 1 game->xstates[mi] &= ~flag;
1693
1694 1 mapscr* scr = origin_scr;
1695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1696 1 scr = get_scr(cmap, cscr);
1697
1698
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1699 {
1700 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1701 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1702
1703 std::vector<int32_t> done;
1704 bool looped = (nmap==cmap+1 && nscr==cscr);
1705
1706 while((nmap!=0) && !looped && !(nscr>=128))
1707 {
1708 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1709 {
1710 log_state_change(nmap, nscr, "ExState change carried over");
1711 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1712 }
1713
1714 cmap=nmap;
1715 cscr=nscr;
1716 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1717 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1718
1719 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1720 {
1721 if(*it == ((nmap-1)<<7)+nscr)
1722 looped = true;
1723 }
1724
1725 done.push_back(((nmap-1)<<7)+nscr);
1726 }
1727 }
1728 2 }
1729 34 bool getxmapflag(int32_t screen, uint32_t flag)
1730 {
1731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1732 34 return getxmapflag_mi(mi, flag);
1733 }
1734 469158480 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1735 {
1736 469158480 return (game->xstates[mi] & flag) != 0;
1737 }
1738
1739 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1740 {
1741
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1742 return;
1743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1744 return;
1745
1746
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1747
1748 4 int cscr = mi % MAPSCRSNORMAL;
1749 4 int cmap = mi / MAPSCRSNORMAL;
1750
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1751
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1752 else
1753 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1754 4 }
1755 469158441 bool getxdoor_mi(uint mi, uint dir, uint ind)
1756 {
1757
3/6
✓ Branch 0 taken 469158441 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 469158441 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 469158441 times.
469158441 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1758 return false;
1759 469158441 return (game->xdoors[mi][dir] & (1<<ind));
1760 469158441 }
1761 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1762 {
1763 9 int mi = mapind(cur_map, screen);
1764 9 return getxdoor_mi(mi,dir,ind);
1765 }
1766
1767 401 void set_doorstate_mi(uint mi, uint dir)
1768 {
1769
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1770 return;
1771 401 setmapflag_mi(mi, mDOOR_UP << dir);
1772
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1773 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1774 401 }
1775 401 void set_doorstate(uint screen, uint dir)
1776 {
1777 401 int mi = mapind(cur_map, screen);
1778 401 set_doorstate_mi(mi, dir);
1779 401 }
1780
1781 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1782 {
1783
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1784 return;
1785 2 setxdoor_mi(mi, dir, ind, state);
1786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1787 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1788 2 }
1789
1790 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1791 {
1792 2 int mi = mapind(cur_map, screen);
1793 2 set_xdoorstate_mi(mi, dir, ind, state);
1794 2 }
1795
1796 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1797 // returns: -1 = not a warp screen
1798 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1799 {
1800 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1801
1802
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1803 return -1;
1804
1805 57 int32_t ring=scr->catchall;
1806 57 int32_t size=QMisc.warp[ring].size;
1807
1808
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1809 return -2;
1810
1811 57 int32_t index=-1;
1812
1813
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1814
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1815 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1816 57 index=i;
1817
1818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1819 return -3;
1820
1821 57 index = (index+dw)%size;
1822 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1823 57 }
1824
1825 14707204 void update_combo_cycling()
1826 {
1827 14707204 auto& combo_cache = combo_caches::can_cycle;
1828
1829 static int32_t newdata[176];
1830 static int32_t newcset[176];
1831 static bool initialized=false;
1832
1833 // Just a simple bit of optimization
1834
2/2
✓ Branch 0 taken 14706895 times.
✓ Branch 1 taken 309 times.
14707204 if(!initialized)
1835 {
1836
2/2
✓ Branch 0 taken 54384 times.
✓ Branch 1 taken 309 times.
54693 for(int32_t i=0; i<176; i++)
1837 {
1838 54384 newdata[i]=-1;
1839 54384 newcset[i]=-1;
1840 54384 }
1841
1842 309 initialized=true;
1843 309 }
1844
1845 14707204 std::set<uint16_t> restartanim;
1846
1847
1/2
✓ Branch 0 taken 14707204 times.
✗ Branch 1 not taken.
29803776 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1848 15096572 int screen = scr->screen;
1849 int32_t x;
1850
1851
2/2
✓ Branch 0 taken 2656996672 times.
✓ Branch 1 taken 15096572 times.
2672093244 for(int32_t i=0; i<176; i++)
1852 {
1853 2656996672 x=scr->data[i];
1854 2656996672 auto& mini_cmb = combo_cache.minis[x];
1855
2/2
✓ Branch 0 taken 3267281 times.
✓ Branch 1 taken 2653729391 times.
2656996672 if (!mini_cmb.can_cycle)
1856 2653729391 continue;
1857
1858 3267281 newcombo const& cmb = combobuf[x];
1859
1860 //time to restart
1861
4/4
✓ Branch 0 taken 900164 times.
✓ Branch 1 taken 2367117 times.
✓ Branch 2 taken 473169 times.
✓ Branch 3 taken 426995 times.
3267281 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1862 {
1863 426995 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 426995 times.
426995 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1865 426995 newdata[i] = c;
1866
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 426975 times.
426995 if(!(cmb.animflags & AF_CYCLENOCSET))
1867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 426975 times.
426975 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1868
1869
2/2
✓ Branch 0 taken 425951 times.
✓ Branch 1 taken 1044 times.
426995 if(combobuf[c].animflags & AF_CYCLE)
1870 {
1871 1044 restartanim.insert(c);
1872 1044 }
1873 426995 }
1874 3267281 }
1875
1876 15096572 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1877
2/2
✓ Branch 0 taken 2656996672 times.
✓ Branch 1 taken 15096572 times.
2672093244 for(int32_t i=0; i<176; i++)
1878 {
1879
2/2
✓ Branch 0 taken 426995 times.
✓ Branch 1 taken 2656569677 times.
2656996672 if(newdata[i]==-1)
1880 2656569677 continue;
1881
1882 426995 rpos_t rpos = (rpos_t)(rpos_base + i);
1883 426995 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1884 426995 screen_combo_modify_preroutine(rpos_handle);
1885 426995 scr->data[i]=newdata[i];
1886
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 426975 times.
426995 if(newcset[i]>-1)
1887 426975 scr->cset[i]=newcset[i];
1888 426995 screen_combo_modify_postroutine(rpos_handle);
1889
1890 426995 newdata[i]=-1;
1891 426995 newcset[i]=-1;
1892 426995 }
1893
1894 15096572 word c = scr->numFFC();
1895
2/2
✓ Branch 0 taken 15096572 times.
✓ Branch 1 taken 451320547 times.
466417119 for(word i=0; i<c; i++)
1896 {
1897 451320547 ffcdata& ffc = scr->ffcs[i];
1898 451320547 auto& mini_cmb = combo_cache.minis[ffc.data];
1899
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 451316374 times.
451320547 if (!mini_cmb.can_cycle)
1900 451316374 continue;
1901
1902 4173 newcombo const& cmb = combobuf[ffc.data];
1903
1904 //time to restart
1905
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1906 {
1907 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1909 108 zc_ffc_set(ffc, c);
1910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1911
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1912
1913
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1914 {
1915 60 restartanim.insert(ffc.data);
1916 60 }
1917 108 }
1918 4173 }
1919
1920
2/2
✓ Branch 0 taken 8345910 times.
✓ Branch 1 taken 6750662 times.
15096572 if(get_qr(qr_CMBCYCLELAYERS))
1921 {
1922
2/2
✓ Branch 0 taken 40503972 times.
✓ Branch 1 taken 6750662 times.
47254634 for(int32_t j=1; j<=6; j++)
1923 {
1924 40503972 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1925
2/2
✓ Branch 0 taken 10894349 times.
✓ Branch 1 taken 29609623 times.
40503972 if (!layer_scr)
1926 29609623 continue;
1927
1928
2/2
✓ Branch 0 taken 1917405424 times.
✓ Branch 1 taken 10894349 times.
1928299773 for(int32_t i=0; i<176; i++)
1929 {
1930 1917405424 x=layer_scr->data[i];
1931 1917405424 auto& mini_cmb = combo_cache.minis[x];
1932
2/2
✓ Branch 0 taken 2230074 times.
✓ Branch 1 taken 1915175350 times.
1917405424 if (!mini_cmb.can_cycle)
1933 1915175350 continue;
1934
1935 2230074 newcombo const& cmb = combobuf[x];
1936
1937 //time to restart
1938
4/4
✓ Branch 0 taken 48416 times.
✓ Branch 1 taken 2181658 times.
✓ Branch 2 taken 37483 times.
✓ Branch 3 taken 10933 times.
2230074 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1939 {
1940 10933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1942 10933 newdata[i] = c;
1943
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 10864 times.
10933 if(!(cmb.animflags & AF_CYCLENOCSET))
1944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1945 69 else newcset[i] = layer_scr->cset[i];
1946
1947
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 9983 times.
10933 if(combobuf[c].animflags & AF_CYCLE)
1948 {
1949 9983 restartanim.insert(c);
1950 9983 }
1951 10933 }
1952 2230074 }
1953
1954
2/2
✓ Branch 0 taken 1917405424 times.
✓ Branch 1 taken 10894349 times.
1928299773 for (int32_t i=0; i<176; i++)
1955 {
1956
2/2
✓ Branch 0 taken 1917394491 times.
✓ Branch 1 taken 10933 times.
1917405424 if(newdata[i]!=-1)
1957 {
1958 10933 layer_scr->data[i]=newdata[i];
1959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 if(newcset[i]>-1)
1960 10933 layer_scr->cset[i]=newcset[i];
1961 10933 newdata[i]=-1;
1962 10933 newcset[i]=-1;
1963 10933 }
1964 1917405424 }
1965 10894349 }
1966 6750662 }
1967 15096572 });
1968
1969
2/2
✓ Branch 0 taken 14707204 times.
✓ Branch 1 taken 2661 times.
14709865 for (auto i : restartanim)
1970 {
1971 2661 combobuf[i].tile = combobuf[i].o_tile;
1972 2661 combobuf[i].cur_frame=0;
1973 2661 combobuf[i].aclk = 0;
1974
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1975 }
1976 14707204 }
1977
1978 1205731978 bool iswater_type(int32_t type)
1979 {
1980 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1981 1205731978 return (combo_class_buf[type].water!=0);
1982 }
1983
1984 bool iswater(int32_t combo)
1985 {
1986 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1987 }
1988 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1989 {
1990 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1991 }
1992
1993 // (x, y) are world coordinates
1994 58540123 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1995 {
1996
8/8
✓ Branch 0 taken 58494157 times.
✓ Branch 1 taken 45966 times.
✓ Branch 2 taken 58453954 times.
✓ Branch 3 taken 40203 times.
✓ Branch 4 taken 58387502 times.
✓ Branch 5 taken 66452 times.
✓ Branch 6 taken 59413 times.
✓ Branch 7 taken 58328089 times.
58540123 if (x<0 || x>=world_w || y<0 || y>=world_h)
1997 212034 return false;
1998
1999 58328089 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2000 58540123 }
2001
2002 97001355 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2003 {
2004 DCHECK_LAYER_NEG1_INDEX(layer);
2005 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2006 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2007
2008 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2009
2/2
✓ Branch 0 taken 57355583 times.
✓ Branch 1 taken 39645772 times.
97001355 if (get_qr(qr_SMARTER_WATER))
2010 {
2011
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57355583 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57355583 if (DRIEDLAKE) return 0;
2012
5/6
✓ Branch 0 taken 19560102 times.
✓ Branch 1 taken 37795481 times.
✓ Branch 2 taken 6518562 times.
✓ Branch 3 taken 13041540 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518562 times.
57355583 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2013 {
2014
2/2
✓ Branch 0 taken 37777960 times.
✓ Branch 1 taken 12368210 times.
50146170 for (int32_t m = layer; m <= 1; m++)
2015 {
2016
5/6
✓ Branch 0 taken 24736420 times.
✓ Branch 1 taken 13041540 times.
✓ Branch 2 taken 12368210 times.
✓ Branch 3 taken 12368210 times.
✓ Branch 4 taken 12368210 times.
✗ Branch 5 not taken.
50146170 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2017
1/2
✓ Branch 0 taken 12368210 times.
✗ Branch 1 not taken.
24736420 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2018 {
2019 37777960 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2020
2/2
✓ Branch 0 taken 37104630 times.
✓ Branch 1 taken 673330 times.
37777960 if (checkwater > 0)
2021 {
2022
2/2
✓ Branch 0 taken 673272 times.
✓ Branch 1 taken 58 times.
673330 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2023 673330 return checkwater;
2024 }
2025 37104630 }
2026 37104630 }
2027 12368210 return 0;
2028 }
2029 else
2030 {
2031
2/2
✓ Branch 0 taken 44328716 times.
✓ Branch 1 taken 42139889 times.
86468605 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2032 {
2033 44328716 int32_t tx2=((i&2)<<2)+x;
2034 44328716 int32_t ty2=((i&1)<<3)+y;
2035 44328716 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2036 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2037
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 44307043 times.
44328716 if (!fullcheck)
2038 {
2039 44307043 tx2 = x;
2040 44307043 ty2 = y;
2041
2/2
✓ Branch 0 taken 24875722 times.
✓ Branch 1 taken 19431321 times.
44307043 if(tx2&8) b+=2;
2042
2/2
✓ Branch 0 taken 20524614 times.
✓ Branch 1 taken 23782429 times.
44307043 if(ty2&8) b+=1;
2043 44307043 }
2044
2/2
✓ Branch 0 taken 94775306 times.
✓ Branch 1 taken 43484483 times.
138259789 for (int32_t m = layer; m <= 1; m++)
2045 {
2046 94775306 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2047
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77039579 times.
94775306 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2048 {
2049
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735727 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735727 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2050 {
2051 return 0;
2052 }
2053 17735727 }
2054 else
2055 {
2056
4/4
✓ Branch 0 taken 179102 times.
✓ Branch 1 taken 76860477 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 127950 times.
77039579 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2057 {
2058 127950 return 0;
2059 }
2060 }
2061
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 76911629 times.
94647356 if (get_qr(qr_NO_SOLID_SWIM))
2062 {
2063
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 76860477 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 716283 times.
✓ Branch 5 taken 76144194 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 712822 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
76911629 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2064 {
2065 716283 return 0;
2066 }
2067 76195346 }
2068
3/6
✓ Branch 0 taken 320336 times.
✓ Branch 1 taken 93610737 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320336 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
93931073 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2069 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2070 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2071 {
2072 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2073 }
2074 93931073 }
2075
2076 131351049 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2077
2/2
✓ Branch 0 taken 87338701 times.
✓ Branch 1 taken 527865 times.
87866566 if (ffcIsAt(ffc_handle, tx2, ty2))
2078 {
2079 527865 auto ty = ffc_handle.ctype();
2080
4/6
✓ Branch 0 taken 527865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527865 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2081 527865 return true;
2082 }
2083
2084 87338701 return false;
2085 87866566 });
2086
2/2
✓ Branch 0 taken 42956618 times.
✓ Branch 1 taken 527865 times.
43484483 if (found_ffc_not_water) return 0;
2087
2088
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 42941945 times.
42956618 if(!i)
2089 {
2090 127956725 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2091
1/2
✓ Branch 0 taken 85014780 times.
✗ Branch 1 not taken.
85014780 if (ffcIsAt(ffc_handle, tx2, ty2))
2092 {
2093 auto ty = ffc_handle.ctype();
2094 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2095 return true;
2096 }
2097
2098 85014780 return false;
2099 85014780 });
2100
1/2
✓ Branch 0 taken 42941945 times.
✗ Branch 1 not taken.
42941945 if (found_ffc_water)
2101 {
2102 if(out_handle) *out_handle = *found_ffc_water;
2103 return found_ffc_water->data();
2104 }
2105 42941945 }
2106
2107 42956618 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2108
2/2
✓ Branch 0 taken 42912124 times.
✓ Branch 1 taken 44494 times.
42956618 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2109
7/12
✓ Branch 0 taken 42631519 times.
✓ Branch 1 taken 280605 times.
✓ Branch 2 taken 10830537 times.
✓ Branch 3 taken 31800982 times.
✓ Branch 4 taken 10352353 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10352353 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42912124 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2110 {
2111
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757562 times.
758789 if (i == 0)
2112 {
2113
2/2
✓ Branch 0 taken 757553 times.
✓ Branch 1 taken 9 times.
757562 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2114 757562 return checkcombo;
2115 }
2116 1227 }
2117 42154562 }
2118 42139889 return 0;
2119 }
2120 }
2121 else
2122 {
2123 39645772 int32_t b = 0;
2124
2/2
✓ Branch 0 taken 20550363 times.
✓ Branch 1 taken 19095409 times.
39645772 if(x&8) b+=2;
2125
2/2
✓ Branch 0 taken 15377475 times.
✓ Branch 1 taken 24268297 times.
39645772 if(y&8) b+=1;
2126
1/2
✓ Branch 0 taken 39645772 times.
✗ Branch 1 not taken.
39645772 if (get_qr(qr_NO_SOLID_SWIM))
2127 {
2128 if (combobuf[combo].walk&(1<<b))
2129 {
2130 return 0;
2131 }
2132 }
2133
1/2
✓ Branch 0 taken 39645772 times.
✗ Branch 1 not taken.
39645772 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2134
8/8
✓ Branch 0 taken 37962384 times.
✓ Branch 1 taken 1683388 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37794439 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1767166 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39645772 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2135 {
2136
2/2
✓ Branch 0 taken 1928827 times.
✓ Branch 1 taken 30 times.
1928857 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2137 1928857 return combo;
2138 }
2139 37958213 return 0;
2140 }
2141 97242653 }
2142
2143 326 bool isdamage_type(int32_t type)
2144 {
2145
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2146 {
2147 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2148 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2149 return true;
2150 }
2151 326 return false;
2152 326 }
2153
2154 2556587736 bool ispitfall_type(int32_t type)
2155 {
2156 2556587736 return combo_class_buf[type].pit != 0;
2157 }
2158
2159 2556587736 bool ispitfall(int32_t combo)
2160 {
2161 2556587736 return ispitfall_type(combobuf[combo].type);
2162 }
2163
2164 276439940 bool ispitfall(int32_t x, int32_t y)
2165 {
2166
2/2
✓ Branch 0 taken 1456039 times.
✓ Branch 1 taken 274983901 times.
276439940 if(int32_t c = MAPFFCOMBO(x,y))
2167 {
2168 1456039 return ispitfall(c) ? true : false;
2169 }
2170 274983901 int32_t c = MAPCOMBOL(2,x,y);
2171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274983901 times.
274983901 if(ispitfall(c)) return true;
2172
2/2
✓ Branch 0 taken 261872757 times.
✓ Branch 1 taken 13111144 times.
274983901 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2173 {
2174
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 261872757 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
261872757 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2175 261872757 }
2176 else
2177 {
2178
3/4
✓ Branch 0 taken 2780 times.
✓ Branch 1 taken 13108364 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2780 times.
13111144 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2179 }
2180 274981121 c = MAPCOMBOL(1,x,y);
2181
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 274981097 times.
274981121 if(ispitfall(c)) return true;
2182
2183
2/2
✓ Branch 0 taken 261872757 times.
✓ Branch 1 taken 13108340 times.
274981097 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2184 {
2185
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 261872757 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
261872757 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2186 261872757 }
2187 else
2188 {
2189
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13095268 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13108340 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2190 }
2191 274972320 c = MAPCOMBO(x,y);
2192
2/2
✓ Branch 0 taken 70747 times.
✓ Branch 1 taken 274901573 times.
274972320 if(ispitfall(c)) return true;
2193 274901573 return false;
2194 276439940 }
2195
2196 582977247 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2197 {
2198
2/2
✓ Branch 0 taken 9281019 times.
✓ Branch 1 taken 573696228 times.
582977247 if(int32_t c = MAPFFCOMBO(x,y))
2199 {
2200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9281019 times.
9281019 return ispitfall(c) ? c : 0;
2201 }
2202 573696228 int32_t c = MAPCOMBOL(2,x,y);
2203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 573696228 times.
573696228 if(ispitfall(c)) return c;
2204
2205
2/2
✓ Branch 0 taken 530157426 times.
✓ Branch 1 taken 43538802 times.
573696228 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2206 {
2207
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 530157426 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
530157426 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2208 530157426 }
2209 else
2210 {
2211
3/4
✓ Branch 0 taken 35747 times.
✓ Branch 1 taken 43503055 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35747 times.
43538802 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2212 }
2213 573660481 c = MAPCOMBOL(1,x,y);
2214
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 573660203 times.
573660481 if(ispitfall(c)) return c;
2215
2216
2/2
✓ Branch 0 taken 530157426 times.
✓ Branch 1 taken 43502777 times.
573660203 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2217 {
2218
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 530157426 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
530157426 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2219 530157426 }
2220 else
2221 {
2222
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43358420 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43502777 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2223 }
2224 573556474 c = MAPCOMBO(x,y);
2225
2/2
✓ Branch 0 taken 176844 times.
✓ Branch 1 taken 573379630 times.
573556474 if(ispitfall(c)) return c;
2226 573379630 return 0;
2227 582977247 }
2228 51 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2229 {
2230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(int32_t c = MAPFFCOMBO(x,y))
2231 {
2232 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2233 }
2234 51 int32_t c = MAPCOMBOL(2,x,y);
2235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2236
2237
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2238 {
2239
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2240 return nullopt;
2241 6 }
2242 else
2243 {
2244
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2245 return nullopt;
2246 }
2247 51 c = MAPCOMBOL(1,x,y);
2248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2249
2250
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2251 {
2252
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2253 return nullopt;
2254 6 }
2255 else
2256 {
2257
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2258 return nullopt;
2259 }
2260 51 c = MAPCOMBO(x,y);
2261
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2262 return nullopt;
2263 51 }
2264 5426430 bool check_icy(newcombo const& cmb, int type)
2265 {
2266
2/2
✓ Branch 0 taken 5426265 times.
✓ Branch 1 taken 165 times.
5426430 if(cmb.type != cICY)
2267 5426265 return false;
2268
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2269 {
2270 case ICY_BLOCK:
2271 return cmb.usrflags&cflag1;
2272 case ICY_PLAYER:
2273 165 return cmb.usrflags&cflag2;
2274 }
2275 return false;
2276 5426430 }
2277 1811334 int get_icy(int x, int y, int type)
2278 {
2279 1811334 int32_t c = MAPCOMBOL(2,x,y);
2280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1811334 times.
1811334 if(check_icy(combobuf[c], type)) return c;
2281
2282 1811334 int screen = get_screen_for_world_xy(x, y);
2283
2284 1811334 mapscr* scr = get_scr_layer_valid(screen, 2);
2285
2/2
✓ Branch 0 taken 430739 times.
✓ Branch 1 taken 1380595 times.
1811334 if (scr)
2286 {
2287
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 1380119 times.
1380595 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2288 {
2289
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 476 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
476 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2290 476 }
2291 else
2292 {
2293
3/4
✓ Branch 0 taken 3048 times.
✓ Branch 1 taken 1377071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3048 times.
1380119 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2294 }
2295 1377547 }
2296 1808286 c = MAPCOMBOL(1,x,y);
2297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1808286 times.
1808286 if(check_icy(combobuf[c], type)) return c;
2298
2299 1808286 scr = get_scr_layer_valid(screen, 1);
2300
2/2
✓ Branch 0 taken 73612 times.
✓ Branch 1 taken 1734674 times.
1808286 if (scr)
2301 {
2302
2/2
✓ Branch 0 taken 1864 times.
✓ Branch 1 taken 1732810 times.
1734674 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2303 {
2304
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1864 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1864 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2305 1864 }
2306 else
2307 {
2308
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1731169 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1732810 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2309 }
2310 1733033 }
2311 1806645 c = MAPCOMBO(x,y);
2312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1806645 times.
1806645 if(check_icy(combobuf[c], type)) return c;
2313 1806645 return 0;
2314 1811334 }
2315
2316 12977496 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2317 {
2318
8/8
✓ Branch 0 taken 12970698 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 12961832 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 12950200 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 427844 times.
✓ Branch 7 taken 12522356 times.
12977496 if(x<0 || x>=world_w || y<0 || y>=world_h)
2319 455140 return false;
2320
2321 12522356 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2322
2/4
✓ Branch 0 taken 12522356 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12522356 times.
12522356 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2323 return true;
2324
2325 12522356 change_rpos_handle_layer(rpos_handle, 1);
2326
2/2
✓ Branch 0 taken 7562558 times.
✓ Branch 1 taken 4959798 times.
12522356 if (rpos_handle.scr->is_valid())
2327
3/4
✓ Branch 0 taken 4959798 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 4956519 times.
4959798 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2328 3279 return true;
2329
2330 12519077 change_rpos_handle_layer(rpos_handle, 2);
2331
2/2
✓ Branch 0 taken 10835536 times.
✓ Branch 1 taken 1683541 times.
12519077 if (rpos_handle.scr->is_valid())
2332
2/4
✓ Branch 0 taken 1683541 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1683541 times.
1683541 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2333 return true;
2334
2335 12519077 return false;
2336 12977496 }
2337
2338 6552910 bool isSVLadder(int32_t x, int32_t y)
2339 {
2340 6552910 return checkSV(x, y, mfSIDEVIEWLADDER);
2341 }
2342
2343 6424586 bool isSVPlatform(int32_t x, int32_t y)
2344 {
2345 6424586 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2346 }
2347
2348 6424586 bool checkSVLadderPlatform(int32_t x, int32_t y)
2349 {
2350
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6424586 times.
✓ Branch 2 taken 6422789 times.
✓ Branch 3 taken 1797 times.
6424586 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2351 }
2352
2353 1637 bool isstepable(int32_t combo) //can use ladder on it
2354 {
2355
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2356
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2357 {
2358 if(combobuf[combo].usrflags&cflag4)
2359 {
2360 int32_t ldrid = current_item_id(itype_ladder);
2361 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2362 }
2363 }
2364 6 return false;
2365 1637 }
2366
2367 32394 bool isHSGrabbable(newcombo const& cmb)
2368 {
2369
2/2
✓ Branch 0 taken 367 times.
✓ Branch 1 taken 32027 times.
32394 if(cmb.type == cHSGRAB) return true;
2370 32027 return cmb.genflags & cflag1;
2371 32394 }
2372
2373 954 bool isSwitchHookable(newcombo const& cmb)
2374 {
2375
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2376 822 return cmb.genflags & cflag2;
2377 954 }
2378
2379 61015 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2380 {
2381 61015 rpos_t cpos = rpos_t::None;
2382
2/2
✓ Branch 0 taken 63832 times.
✓ Branch 1 taken 124847 times.
61015 if(out_rpos)
2383 {
2384 124847 int32_t id = MAPCOMBO2(layer-1,x,y);
2385
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 96213 times.
124847 if(id > 0)
2386 {
2387 96213 newcombo const& cmb = combobuf[id];
2388
4/4
✓ Branch 0 taken 32352 times.
✓ Branch 1 taken 63861 times.
✓ Branch 2 taken 31916 times.
✓ Branch 3 taken 31945 times.
96213 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2389 32381 }
2390 61015 }
2391
2392 124847 ffcdata* ffc = nullptr;
2393
4/4
✓ Branch 0 taken 28003 times.
✓ Branch 1 taken 96844 times.
✓ Branch 2 taken 24610 times.
✓ Branch 3 taken 3393 times.
124847 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2394 {
2395 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2396
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2397 {
2398 113 auto& cmb = ffc_handle.combo();
2399
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2400 {
2401 77 ffc = ffc_handle.ffc;
2402 77 return false;
2403 }
2404 36 }
2405 6889 return true;
2406 6896 });
2407 3393 }
2408
2409
4/4
✓ Branch 0 taken 61015 times.
✓ Branch 1 taken 63832 times.
✓ Branch 2 taken 436 times.
✓ Branch 3 taken 60579 times.
124847 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2410
4/4
✓ Branch 0 taken 28003 times.
✓ Branch 1 taken 96844 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 27996 times.
124847 if (out_ffc && ffc) *out_ffc = ffc;
2411
2/2
✓ Branch 0 taken 64268 times.
✓ Branch 1 taken 60579 times.
124847 return (cpos != rpos_t::None || ffc);
2412 }
2413
2414 5083 bool ishookshottable(int32_t bx, int32_t by)
2415 {
2416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5083 times.
5083 if(!_walkflag(bx,by,1))
2417 return true;
2418
2419
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5075 times.
5083 if (collide_object(bx, by, 1, 1))
2420 8 return false;
2421
2422 5075 bool ret = true;
2423
2/2
✓ Branch 0 taken 15225 times.
✓ Branch 1 taken 1878 times.
17103 for(int32_t i=2; i>=0; i--)
2424 {
2425 15225 int32_t c = MAPCOMBO2(i-1,bx,by);
2426 15225 int32_t t = combobuf[c].type;
2427
2428
6/6
✓ Branch 0 taken 5075 times.
✓ Branch 1 taken 10150 times.
✓ Branch 2 taken 3808 times.
✓ Branch 3 taken 1267 times.
✓ Branch 4 taken 1878 times.
✓ Branch 5 taken 1930 times.
15225 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2429
2430
3/4
✓ Branch 0 taken 11075 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
12981 bool dried = (iswater_type(t) && DRIEDLAKE);
2431
2432 12028 int32_t b=1;
2433
2434
2/2
✓ Branch 0 taken 5970 times.
✓ Branch 1 taken 6058 times.
12028 if(bx&8) b<<=2;
2435
2436
2/2
✓ Branch 0 taken 3723 times.
✓ Branch 1 taken 8305 times.
12028 if(by&8) b<<=1;
2437
2438
7/8
✓ Branch 0 taken 2070 times.
✓ Branch 1 taken 9958 times.
✓ Branch 2 taken 2070 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 955 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 880 times.
12028 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2439 880 ret = false;
2440 12028 }
2441
2442 1878 return ret;
2443 5083 }
2444
2445 10043 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2446 {
2447
4/4
✓ Branch 0 taken 9464 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9464 times.
✓ Branch 3 taken 579 times.
10043 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2448 {
2449 579 int pos = COMBOPOS(s->stairx,s->stairy);
2450 579 s->data[pos] = s->secretcombo[sSTAIRS];
2451 579 s->cset[pos] = s->secretcset[sSTAIRS];
2452 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2453
2454
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2455 {
2456 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2457 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2458 256 }
2459
2460 579 return true;
2461 }
2462
2463 9464 return false;
2464 10043 }
2465
2466 51577 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2467 {
2468 DCHECK(base_scr->is_valid());
2469
2470 51577 screen_handles_t screen_handles{};
2471 51577 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2472 51577 return screen_handles;
2473 }
2474
2475 56242218 screen_handles_t create_screen_handles(mapscr* base_scr)
2476 {
2477 DCHECK(get_scr(base_scr->screen) == base_scr);
2478 DCHECK(base_scr->is_valid());
2479
2480 56242218 int screen = base_scr->screen;
2481 screen_handles_t screen_handles;
2482 56242218 screen_handles[0] = {base_scr, base_scr, screen, 0};
2483
2/2
✓ Branch 0 taken 337453308 times.
✓ Branch 1 taken 56242218 times.
393695526 for (int i = 1; i <= 6; i++)
2484 337453308 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2485 56242218 return screen_handles;
2486 }
2487
2488 106191 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2489 {
2490 106191 mapscr* scr = screen_handles[0].scr;
2491 106191 bool didit=false;
2492
2493
2/2
✓ Branch 0 taken 106191 times.
✓ Branch 1 taken 18689616 times.
18795807 for(int32_t i=0; i<176; i++)
2494 {
2495 18689616 newcombo const& cmb = combobuf[scr->data[i]];
2496
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18689290 times.
18689616 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2497
4/4
✓ Branch 0 taken 18687772 times.
✓ Branch 1 taken 1518 times.
✓ Branch 2 taken 1091 times.
✓ Branch 3 taken 18686681 times.
18689290 if((cmb.type == what1) || (cmb.type== what2))
2498 {
2499 2609 scr->data[i]++;
2500 2609 didit=true;
2501 2609 }
2502 18689290 }
2503
2504
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106099 times.
106191 if (do_layers)
2505 {
2506
2/2
✓ Branch 0 taken 636594 times.
✓ Branch 1 taken 106099 times.
742693 for(int32_t j=1; j<=6; j++)
2507 {
2508 636594 mapscr* layer_scr = screen_handles[j].scr;
2509
2/2
✓ Branch 0 taken 173025 times.
✓ Branch 1 taken 463569 times.
636594 if (!layer_scr) continue;
2510
2511
2/2
✓ Branch 0 taken 30452400 times.
✓ Branch 1 taken 173025 times.
30625425 for(int32_t i=0; i<176; i++)
2512 {
2513 30452400 newcombo const& cmb = combobuf[layer_scr->data[i]];
2514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30452400 times.
30452400 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2515
4/4
✓ Branch 0 taken 30452317 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30452052 times.
30452400 if((cmb.type== what1) || (cmb.type== what2))
2516 {
2517 348 layer_scr->data[i]++;
2518 348 didit=true;
2519 348 }
2520 30452400 }
2521 173025 }
2522 106099 }
2523
2524 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2525
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85785 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106191 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2526 {
2527 20406 word c = scr->numFFC();
2528
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2529 {
2530 73350 ffcdata* ffc = &scr->ffcs[i];
2531 73350 newcombo const& cmb = combobuf[ffc->data];
2532
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2533
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2534 {
2535 zc_ffc_modify(*ffc, 1);
2536 didit=true;
2537 }
2538 73350 }
2539 20406 }
2540
2541 106191 return didit;
2542 }
2543
2544 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2545 {
2546 14 int screen = screen_handles[0].scr->screen;
2547
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2548 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2549 }
2550 469158446 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2551 {
2552 469158446 bool didit=false;
2553
2/2
✓ Branch 0 taken 469129588 times.
✓ Branch 1 taken 28858 times.
469158446 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2554
2555 28858 mapscr* s = screen_handles[0].scr;
2556 28858 int screen = s->screen;
2557 28858 bool is_active_screen = is_in_current_region(s);
2558
2559 24248394 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2560
4/4
✓ Branch 0 taken 24207920 times.
✓ Branch 1 taken 11616 times.
✓ Branch 2 taken 24206112 times.
✓ Branch 3 taken 1808 times.
24219536 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2561 1808 didit = true;
2562
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 24154101 times.
24217728 else switch (rpos_handle.ctype())
2563 {
2564 case cLOCKBLOCK: case cLOCKBLOCK2:
2565 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2566 case cCHEST: case cCHEST2:
2567 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2568 case cBOSSCHEST: case cBOSSCHEST2:
2569 {
2570 63627 auto& cmb = rpos_handle.combo();
2571
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2572
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2573 {
2574 29 rpos_handle.increment_data();
2575 29 didit=true;
2576 29 }
2577 62059 break;
2578 }
2579 }
2580 24219536 });
2581
2582
4/4
✓ Branch 0 taken 28817 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 19197 times.
✓ Branch 3 taken 9620 times.
28858 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2583 {
2584 19197 word c = s->numFFC();
2585 19197 int screen_index_offset = get_region_screen_offset(screen);
2586
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 19197 times.
56037 for (uint8_t i = 0; i < c; i++)
2587 {
2588 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2589 36840 auto& cmb = ffc_handle.combo();
2590
3/4
✓ Branch 0 taken 36840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36824 times.
✓ Branch 3 taken 16 times.
36840 if(triggers && force_ex_trigger_ffc_any(ffc_handle, xflag))
2591 16 didit = true;
2592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2593 {
2594 case cLOCKBLOCK: case cLOCKBLOCK2:
2595 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2596 case cCHEST: case cCHEST2:
2597 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2598 case cBOSSCHEST: case cBOSSCHEST2:
2599 {
2600 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2601 if(cmb.attribytes[5] == xflag)
2602 {
2603 zc_ffc_modify(*ffc_handle.ffc, 1);
2604 didit=true;
2605 }
2606 break;
2607 }
2608 }
2609 36840 }
2610 19197 }
2611
2612 28858 return didit;
2613 469158446 }
2614
2615 14609395 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2616 {
2617 14609395 int screen = screen_handles[0].screen;
2618
2/2
✓ Branch 0 taken 386644 times.
✓ Branch 1 taken 14222751 times.
14609395 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2619 14609395 clear_xstatecombos_mi(screen_handles, mi, triggers);
2620 14609395 }
2621
2622 14661201 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2623 {
2624
2/2
✓ Branch 0 taken 469158432 times.
✓ Branch 1 taken 14661201 times.
483819633 for (int q = 0; q < 32; ++q)
2625 {
2626 469158432 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2627 469158432 }
2628 14661201 }
2629
2630 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2631 {
2632 int screen = screen_handles[0].screen;
2633 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2634 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2635 }
2636 469158432 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2637 {
2638 469158432 bool didit=false;
2639
2/2
✓ Branch 0 taken 469157119 times.
✓ Branch 1 taken 1313 times.
469158432 if (!getxdoor_mi(mi, dir, ind)) return false;
2640
2641 1313 mapscr* scr = screen_handles[0].scr;
2642 1313 int screen = scr->screen;
2643 1313 bool is_active_screen = is_in_current_region(scr);
2644
2645 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2646
3/4
✓ Branch 0 taken 924352 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2647 11 didit = true;
2648 else; //future door combo types?
2649 924352 });
2650
2651
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2652 {
2653 1313 word c = scr->numFFC();
2654 1313 int screen_index_offset = get_region_screen_offset(screen);
2655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2656 {
2657 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2658 if (triggers && force_ex_door_trigger_ffc_any(ffc_handle, dir, ind))
2659 didit = true;
2660 else; //future door combo types?
2661 }
2662 1313 }
2663
2664 1313 return didit;
2665 469158432 }
2666
2667 14609395 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2668 {
2669 14609395 int screen = screen_handles[0].screen;
2670
2/2
✓ Branch 0 taken 386644 times.
✓ Branch 1 taken 14222751 times.
14609395 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2671 14609395 return clear_xdoors_mi(screen_handles, mi, triggers);
2672 }
2673
2674 14661201 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2675 {
2676
2/2
✓ Branch 0 taken 58644804 times.
✓ Branch 1 taken 14661201 times.
73306005 for (int dir = 0; dir < 4; ++dir)
2677
2/2
✓ Branch 0 taken 469158432 times.
✓ Branch 1 taken 58644804 times.
527803236 for (int q = 0; q < 8; ++q)
2678 527803236 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2679 14661201 }
2680
2681 757 bool remove_lockblocks(const screen_handles_t& screen_handles)
2682 {
2683 757 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2684 }
2685
2686 93 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2687 {
2688 93 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2689 }
2690
2691 76553 bool remove_chests(const screen_handles_t& screen_handles)
2692 {
2693 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2694 }
2695
2696 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2697 {
2698 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2699 }
2700
2701 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2702 {
2703 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2704 }
2705
2706 1382910 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2707 {
2708 1382910 int32_t ct=rpos_handle.ctype();
2709
2710
6/6
✓ Branch 0 taken 1382290 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1382038 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1381930 times.
✓ Branch 5 taken 108 times.
1382910 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2711 1381930 return;
2712
2713 2465 auto [cx, cy] = rpos_handle.xy();
2714
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2715 {
2716 case cL_STATUE:
2717 620 cx += 4;
2718 620 cy += 7;
2719 620 break;
2720
2721 case cR_STATUE:
2722 252 cx -= 8;
2723 252 cy -= 1;
2724 252 break;
2725
2726 case cC_STATUE:
2727 108 break;
2728 }
2729
2730
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2731 {
2732 // Finds the smallest enemy ID
2733
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2734 {
2735 346 guys.del(j);
2736 346 }
2737 1485 }
2738 1382910 }
2739
2740 15 static int32_t findtrigger(int32_t screen)
2741 {
2742 15 int32_t checkflag=0;
2743 15 int32_t ret = 0;
2744
2745 mapscr* screens[7];
2746
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2747 {
2748 105 screens[j] = get_scr_layer_valid(screen, j);
2749 105 }
2750
2751 15 bool sflag = false;
2752
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2753 {
2754
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2755 {
2756 26752 mapscr* scr = screens[layer+1];
2757
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2758
2759
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2760 8272 checkflag = scr->sflag[j];
2761 else
2762 8272 checkflag = combobuf[scr->data[j]].flag;
2763 16544 sflag = !sflag;
2764
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2765
2766
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2767 {
2768 case mfANYFIRE:
2769 case mfSTRONGFIRE:
2770 case mfMAGICFIRE:
2771 case mfDIVINEFIRE:
2772 case mfARROW:
2773 case mfSARROW:
2774 case mfGARROW:
2775 case mfSBOMB:
2776 case mfBOMB:
2777 case mfBRANG:
2778 case mfMBRANG:
2779 case mfFBRANG:
2780 case mfWANDMAGIC:
2781 case mfREFMAGIC:
2782 case mfREFFIREBALL:
2783 case mfSWORD:
2784 case mfWSWORD:
2785 case mfMSWORD:
2786 case mfXSWORD:
2787 case mfSWORDBEAM:
2788 case mfWSWORDBEAM:
2789 case mfMSWORDBEAM:
2790 case mfXSWORDBEAM:
2791 case mfHOOKSHOT:
2792 case mfWAND:
2793 case mfHAMMER:
2794 case mfSTRIKE:
2795 10 ret += 1;
2796 10 break;
2797 }
2798 16544 }
2799 2640 }
2800
2801 15 return ret;
2802 }
2803
2804 11713 static void log_trigger_secret_reason(TriggerSource source)
2805 {
2806
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11274 times.
11713 if (source == TriggerSource::Singular)
2807 {
2808 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2809 439 }
2810 else
2811 {
2812 11274 const char* source_str = "";
2813
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7160 times.
✓ Branch 3 taken 854 times.
✓ Branch 4 taken 2728 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 52 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11274 switch (source)
2814 {
2815 case TriggerSource::Singular: break;
2816 7160 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2817 854 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2818 2728 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2819 475 case TriggerSource::Script: source_str = "a script"; break;
2820 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2821 52 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2822 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2823 case TriggerSource::SCC: source_str = "SCC"; break;
2824 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2825 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2826 }
2827 11274 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2828 }
2829 11713 }
2830
2831 // single:
2832 // >-1 : the singular triggering combo
2833 // -1: triggered by some other cause
2834 11505 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2835 {
2836 11505 log_trigger_secret_reason(source);
2837
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11066 times.
11505 if (single < 0)
2838 11066 get_screen_state(scr->screen).triggered_secrets = true;
2839
2840 11505 bool do_replay_comment = true;
2841 11505 bool from_active_screen = true;
2842 11505 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2843
2844 // Respect secret state carryovers for active screens.
2845
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11066 times.
11505 if (single >= 0) return;
2846
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 11043 times.
11066 if(scr->nocarry&mSECRET) return;
2847 11043 int cmap = scr->map;
2848 11043 int cscr = scr->screen;
2849 11043 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2850 11043 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2851
2852 11043 std::vector<int32_t> done;
2853
2/2
✓ Branch 0 taken 10871 times.
✓ Branch 1 taken 172 times.
11043 bool looped = (nmap==cmap+1 && nscr==cscr);
2854
2855
6/6
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 10976 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 417 times.
✓ Branch 4 taken 417 times.
✓ Branch 5 taken 11043 times.
11460 while((nmap!=0) && !looped && !(nscr>=128))
2856 {
2857
7/8
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 70 times.
417 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2858 {
2859
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2860
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2861
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2862 4 }
2863
2864 417 cmap=nmap;
2865 417 cscr=nscr;
2866 417 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2867 417 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2868
2869
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 417 times.
803 for(auto it = done.begin(); it != done.end(); it++)
2870 {
2871
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 67 times.
386 if(*it == ((nmap-1)<<7)+nscr)
2872 67 looped = true;
2873 386 }
2874
2875
1/2
✓ Branch 0 taken 417 times.
✗ Branch 1 not taken.
417 done.push_back(((nmap-1)<<7)+nscr);
2876 }
2877 11505 }
2878
2879 2430 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2880 {
2881 2430 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2882 2430 }
2883
2884 17926 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2885 {
2886 17926 mapscr* scr = screen_handles[0].scr;
2887 17926 int screen = scr->screen;
2888
2889 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2890 // slopes in sideview mode (which required loading nearby screens in loadscr).
2891 // TODO(replays): This should just use `screen`.
2892
3/4
✓ Branch 0 taken 17926 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 17387 times.
17926 if (replay_is_active() && do_replay_comment)
2893
4/6
✓ Branch 0 taken 11509 times.
✓ Branch 1 taken 5878 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11509 times.
✓ Branch 4 taken 17387 times.
✗ Branch 5 not taken.
17387 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2894
2895
2/2
✓ Branch 0 taken 6417 times.
✓ Branch 1 taken 11509 times.
17926 if (from_active_screen)
2896 {
2897 5426605 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2898
2/4
✓ Branch 0 taken 5413408 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1688 times.
✗ Branch 3 not taken.
5645333 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2899 230237 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2900 }, ctrigSECRETS);
2901 5415096 });
2902 11509 }
2903
2904 17926 int32_t ft=0; //Flag trigger?
2905 17926 int32_t msflag=0; // Misc. secret flag
2906
2907
2/2
✓ Branch 0 taken 3154976 times.
✓ Branch 1 taken 17926 times.
3172902 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2908 {
2909
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3077712 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3154976 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2910
2911 // Remember the misc. secret flag; if triggered, use this instead
2912
4/4
✓ Branch 0 taken 113841 times.
✓ Branch 1 taken 2964310 times.
✓ Branch 2 taken 49067 times.
✓ Branch 3 taken 64774 times.
3078151 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2913 64774 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2914
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2966147 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3013377 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2915 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2916 else
2917 3013146 msflag=0;
2918
2919
4/4
✓ Branch 0 taken 918968 times.
✓ Branch 1 taken 2159183 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 918896 times.
3078151 if(!high16only || single>=0)
2920 {
2921 2159255 int32_t newflag = -1;
2922
2923
2/2
✓ Branch 0 taken 4318510 times.
✓ Branch 1 taken 2159255 times.
6477765 for(int32_t iter=0; iter<2; ++iter)
2924 {
2925 4318510 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2926
2927
2/2
✓ Branch 0 taken 2159255 times.
✓ Branch 1 taken 2159255 times.
4318510 if(iter==1) checkflag=scr->sflag[i]; //Placed
2928
2929 4318510 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2930
2/2
✓ Branch 0 taken 4306401 times.
✓ Branch 1 taken 12109 times.
4318510 if (ft != -1) //Change the combos for the secret
2931 {
2932 // Use misc. secret flag instead if one is present
2933
2/2
✓ Branch 0 taken 12077 times.
✓ Branch 1 taken 32 times.
12109 if(msflag!=0)
2934 32 ft=msflag;
2935
2936 12109 rpos_handle_t rpos_handle;
2937
2/2
✓ Branch 0 taken 6287 times.
✓ Branch 1 taken 5822 times.
12109 if (from_active_screen)
2938 {
2939 5822 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2940 5822 screen_combo_modify_preroutine(rpos_handle);
2941 5822 }
2942
2943
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12109 times.
12109 if(ft==sSECNEXT)
2944 {
2945 scr->data[i]++;
2946 }
2947 else
2948 {
2949 12109 scr->data[i] = scr->secretcombo[ft];
2950 12109 scr->cset[i] = scr->secretcset[ft];
2951 }
2952 12109 newflag = scr->secretflag[ft];
2953
2954
2/2
✓ Branch 0 taken 6287 times.
✓ Branch 1 taken 5822 times.
12109 if (from_active_screen)
2955 5822 screen_combo_modify_postroutine(rpos_handle);
2956 12109 }
2957 4318510 }
2958
2959
2/2
✓ Branch 0 taken 2147152 times.
✓ Branch 1 taken 12103 times.
2159255 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2960
2961
2/2
✓ Branch 0 taken 12955530 times.
✓ Branch 1 taken 2159255 times.
15114785 for(int32_t j=1; j<=6; j++) //Layers
2962 {
2963 12955530 mapscr* layer_scr = screen_handles[j].scr;
2964
2/2
✓ Branch 0 taken 3152885 times.
✓ Branch 1 taken 9802645 times.
12955530 if (!layer_scr) continue;
2965
2966
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3152160 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3152885 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2967
2968 3152885 int32_t newflag2 = -1;
2969
2970 // Remember the misc. secret flag; if triggered, use this instead
2971
4/4
✓ Branch 0 taken 14121 times.
✓ Branch 1 taken 3138764 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9348 times.
3152885 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2972 9348 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2973
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3016606 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3143537 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2974 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2975 else
2976 3143166 msflag=0;
2977
2978
2/2
✓ Branch 0 taken 6305770 times.
✓ Branch 1 taken 3152885 times.
9458655 for(int32_t iter=0; iter<2; ++iter)
2979 {
2980 6305770 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2981
2/2
✓ Branch 0 taken 3152885 times.
✓ Branch 1 taken 3152885 times.
6305770 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2982
2983 6305770 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2984
2/2
✓ Branch 0 taken 6305292 times.
✓ Branch 1 taken 478 times.
6305770 if (ft != -1) //Change the combos for the secret
2985 {
2986 // Use misc. secret flag instead if one is present
2987
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
2988 2 ft=msflag;
2989
2990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
2991 {
2992 layer_scr->data[i]++;
2993 }
2994 else
2995 {
2996 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
2997 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
2998 }
2999 478 newflag2 = layer_scr->secretflag[ft];
3000 478 int32_t c=layer_scr->data[i];
3001 478 int32_t cs=layer_scr->cset[i];
3002
3003
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3004 {
3005 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3006 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3007 }
3008 478 }
3009 6305770 }
3010
3011
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3152407 times.
3152885 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3012 3152885 }
3013 2159255 }
3014 3078151 }
3015
3016 17926 word c = scr->numFFC();
3017
2/2
✓ Branch 0 taken 504311 times.
✓ Branch 1 taken 17926 times.
522237 for(word i=0; i<c; i++) //FFC 'trigger flags'
3018 {
3019
3/4
✓ Branch 0 taken 490391 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
504311 if(single>=0) if(i+176!=single) continue;
3020
3021
3/4
✓ Branch 0 taken 166189 times.
✓ Branch 1 taken 324202 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166189 times.
490391 if((!high16only)||(single>=0))
3022 {
3023 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3024 {
3025 324202 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3026 //No placed flags yet
3027
3028 324202 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3029
2/2
✓ Branch 0 taken 324171 times.
✓ Branch 1 taken 31 times.
324202 if (ft != -1) //Change the ffc's combo
3030 {
3031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3032 {
3033 zc_ffc_modify(scr->ffcs[i], 1);
3034 }
3035 else
3036 {
3037 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3038 31 scr->ffcs[i].cset = scr->secretcset[ft];
3039 }
3040 31 }
3041 }
3042 324202 }
3043 490391 }
3044
3045
2/2
✓ Branch 0 taken 15536 times.
✓ Branch 1 taken 2390 times.
17926 if(checktrigger) //Hit all triggers->16-31
3046 {
3047 2390 checktrigger=false;
3048
3049
2/2
✓ Branch 0 taken 2381 times.
✓ Branch 1 taken 9 times.
2390 if(scr->flags6&fTRIGGERF1631)
3050 {
3051 9 int32_t tr = findtrigger(screen); //Normal flags
3052
3053
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
3054 {
3055 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3056 5 goto endhe;
3057 }
3058 4 }
3059 2385 }
3060
3061
2/2
✓ Branch 0 taken 3154096 times.
✓ Branch 1 taken 17921 times.
3172017 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3062 {
3063 //If it's an enemies->secret screen, only do the high 16 if told to
3064 //That way you can have secret and burn/bomb entrance separately
3065 3154096 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3066
6/6
✓ Branch 0 taken 2766368 times.
✓ Branch 1 taken 387728 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3068912 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3154096 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3067 {
3068 3088448 int32_t newflag = -1;
3069
3070
2/2
✓ Branch 0 taken 6176896 times.
✓ Branch 1 taken 3088448 times.
9265344 for(int32_t iter=0; iter<2; ++iter)
3071 {
3072 6176896 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3073
3074
2/2
✓ Branch 0 taken 3088448 times.
✓ Branch 1 taken 3088448 times.
6176896 if(iter==1) checkflag=scr->sflag[i]; //Placed
3075
3076
4/4
✓ Branch 0 taken 160545 times.
✓ Branch 1 taken 6016351 times.
✓ Branch 2 taken 94488 times.
✓ Branch 3 taken 66057 times.
6176896 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3077 {
3078 66057 rpos_handle_t rpos_handle;
3079
2/2
✓ Branch 0 taken 9818 times.
✓ Branch 1 taken 56239 times.
66057 if (from_active_screen)
3080 {
3081 56239 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3082 56239 screen_combo_modify_preroutine(rpos_handle);
3083 56239 }
3084
3085 66057 scr->data[i] = scr->secretcombo[checkflag-16+4];
3086 66057 scr->cset[i] = scr->secretcset[checkflag-16+4];
3087 66057 newflag = scr->secretflag[checkflag-16+4];
3088
3089
2/2
✓ Branch 0 taken 9818 times.
✓ Branch 1 taken 56239 times.
66057 if (from_active_screen)
3090 56239 screen_combo_modify_postroutine(rpos_handle);
3091 66057 }
3092 6176896 }
3093
3094
2/2
✓ Branch 0 taken 3022415 times.
✓ Branch 1 taken 66033 times.
3088448 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3095
3096
2/2
✓ Branch 0 taken 18530688 times.
✓ Branch 1 taken 3088448 times.
21619136 for(int32_t j=1; j<=6; j++) //Layers
3097 {
3098 18530688 mapscr* layer_scr = screen_handles[j].scr;
3099
2/2
✓ Branch 0 taken 4827680 times.
✓ Branch 1 taken 13703008 times.
18530688 if (!layer_scr) continue;
3100
3101 4827680 int32_t newflag2 = -1;
3102
3103
2/2
✓ Branch 0 taken 9655360 times.
✓ Branch 1 taken 4827680 times.
14483040 for(int32_t iter=0; iter<2; ++iter)
3104 {
3105 9655360 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3106
3107
2/2
✓ Branch 0 taken 4827680 times.
✓ Branch 1 taken 4827680 times.
9655360 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3108
3109
4/4
✓ Branch 0 taken 150924 times.
✓ Branch 1 taken 9504436 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19302 times.
9655360 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3110 {
3111 19302 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3112 19302 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3113 19302 newflag2 = layer_scr->secretflag[checkflag-16+4];
3114 19302 }
3115 9655360 }
3116
3117
2/2
✓ Branch 0 taken 4808378 times.
✓ Branch 1 taken 19302 times.
4827680 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3118 4827680 }
3119 3088448 }
3120 3154096 }
3121
3122
2/2
✓ Branch 0 taken 504151 times.
✓ Branch 1 taken 17921 times.
522072 for(word i=0; i<c; i++) // FFCs
3123 {
3124
6/6
✓ Branch 0 taken 464324 times.
✓ Branch 1 taken 39827 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 488784 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
504151 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3125 {
3126 492314 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3127
3128 //No placed flags yet
3129
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 492246 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
492314 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3130 {
3131
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3132 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3133 else
3134 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3135 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3136 12 }
3137 492314 }
3138 522072 }
3139
3140 endhe:
3141
3142
1/2
✓ Branch 0 taken 17926 times.
✗ Branch 1 not taken.
17926 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3143 {
3144 if (from_active_screen)
3145 activated_timed_warp = true;
3146 scr->timedwarptics = 0;
3147 }
3148 17926 }
3149
3150 // x,y are world coordinates.
3151 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3152 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3153 13469777 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3154 {
3155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13469777 times.
13469777 if (!is_in_world_bounds(x, y)) return false;
3156
3157 13469777 bool found_cflag = false;
3158 13469777 bool found_nflag = false;
3159 13469777 bool single16 = false;
3160 13469777 rpos_t rpos = rpos_t::None;
3161
3162
2/2
✓ Branch 0 taken 13467700 times.
✓ Branch 1 taken 94276289 times.
107743989 for (int32_t layer = -1; layer < 6; layer++)
3163 {
3164
2/2
✓ Branch 0 taken 94274212 times.
✓ Branch 1 taken 2077 times.
94276289 if (MAPFLAG2(layer, x, y) == flag)
3165 {
3166 2077 found_nflag = true;
3167 2077 break;
3168 }
3169 94274212 }
3170
3171
2/2
✓ Branch 0 taken 13469473 times.
✓ Branch 1 taken 94287163 times.
107756636 for (int32_t layer = -1; layer < 6; layer++)
3172 {
3173
2/2
✓ Branch 0 taken 94286859 times.
✓ Branch 1 taken 304 times.
94287163 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3174 {
3175 304 found_cflag = true;
3176 304 break;
3177 }
3178 94286859 }
3179
3180
2/2
✓ Branch 0 taken 94288439 times.
✓ Branch 1 taken 13469777 times.
107758216 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3181 {
3182
2/2
✓ Branch 0 taken 94273900 times.
✓ Branch 1 taken 14539 times.
94288439 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3183 {
3184
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14427 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14539 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3185 {
3186 112 rpos = COMBOPOS_REGION(x, y);
3187 112 }
3188
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14375 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14427 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3189 {
3190 52 rpos = COMBOPOS_REGION(x, y);
3191 52 single16 = true;
3192 52 }
3193 14539 }
3194
3195
2/2
✓ Branch 0 taken 94286311 times.
✓ Branch 1 taken 2128 times.
94288439 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3196 {
3197
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3198 {
3199 255 rpos = COMBOPOS_REGION(x, y);
3200 255 }
3201
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3202 {
3203 20 rpos = COMBOPOS_REGION(x, y);
3204 20 single16 = true;
3205 20 }
3206 2128 }
3207 94288439 }
3208
3209 13469777 out_rpos = rpos;
3210 13469777 out_single16 = single16;
3211
4/4
✓ Branch 0 taken 13467700 times.
✓ Branch 1 taken 2077 times.
✓ Branch 2 taken 13467398 times.
✓ Branch 3 taken 302 times.
13469777 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3212 13469777 }
3213
3214 4442768 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3215 {
3216
8/8
✓ Branch 0 taken 4442528 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4440631 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4440111 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4439159 times.
4442768 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3217
3218 4439159 mapscr* scr = NULL;
3219 4439159 int32_t screen = -1;
3220 4439159 rpos_t trigger_rpos = rpos_t::None;
3221 4439159 bool single16 = false;
3222
3223 4439159 std::vector<std::pair<int, int>> coords;
3224
1/2
✓ Branch 0 taken 4439159 times.
✗ Branch 1 not taken.
4439159 coords.push_back({x, y});
3225
1/2
✓ Branch 0 taken 4439159 times.
✗ Branch 1 not taken.
4439159 coords.push_back({x + 15, y});
3226
1/2
✓ Branch 0 taken 4439159 times.
✗ Branch 1 not taken.
4439159 coords.push_back({x, y + 15});
3227
1/2
✓ Branch 0 taken 4439159 times.
✗ Branch 1 not taken.
4439159 coords.push_back({x + 15, y + 15});
3228 4439159 std::vector<rpos_t> rposes_seen;
3229
2/2
✓ Branch 0 taken 4436769 times.
✓ Branch 1 taken 17751365 times.
84214344 for (auto [x, y] : coords)
3230 {
3231
2/4
✓ Branch 0 taken 17751365 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17751365 times.
✗ Branch 3 not taken.
35502730 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3232
2/2
✓ Branch 0 taken 17540938 times.
✓ Branch 1 taken 210427 times.
17751365 if (rpos == rpos_t::None)
3233 210427 continue;
3234
3235
4/6
✓ Branch 0 taken 17540938 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17540938 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17540927 times.
35081876 if (MAPFFCOMBOFLAG(x, y) == flag)
3236 {
3237
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3238 11 break;
3239 }
3240
3241 17540927 bool seen = false;
3242
2/2
✓ Branch 0 taken 13469777 times.
✓ Branch 1 taken 22061882 times.
35531659 for (rpos_t r : rposes_seen)
3243 {
3244
2/2
✓ Branch 0 taken 17990732 times.
✓ Branch 1 taken 4071150 times.
22061882 if (r == rpos)
3245 {
3246 4071150 seen = true;
3247 4071150 break;
3248 }
3249 }
3250
2/2
✓ Branch 0 taken 13469777 times.
✓ Branch 1 taken 4071150 times.
17540927 if (seen)
3251 4071150 continue;
3252
3253
1/2
✓ Branch 0 taken 13469777 times.
✗ Branch 1 not taken.
13469777 rposes_seen.push_back(rpos);
3254
4/6
✓ Branch 0 taken 13469777 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13469777 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2379 times.
✓ Branch 5 taken 13467398 times.
26939554 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3255 {
3256
2/4
✓ Branch 0 taken 2379 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2379 times.
✗ Branch 3 not taken.
4758 screen = get_screen_for_world_xy(x, y);
3257 2379 break;
3258 }
3259 }
3260
3261
3/4
✓ Branch 0 taken 2390 times.
✓ Branch 1 taken 4436769 times.
✓ Branch 2 taken 2390 times.
✗ Branch 3 not taken.
4439159 if (screen != -1) scr = get_scr(screen);
3262
2/2
✓ Branch 0 taken 2390 times.
✓ Branch 1 taken 4436769 times.
4439159 if (!scr) return false;
3263
3264
2/2
✓ Branch 0 taken 1951 times.
✓ Branch 1 taken 439 times.
2390 if (trigger_rpos == rpos_t::None)
3265 {
3266 1951 checktrigger = true;
3267
1/2
✓ Branch 0 taken 1951 times.
✗ Branch 1 not taken.
1951 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3268 1951 }
3269 else
3270 {
3271 439 checktrigger = true;
3272
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3273 }
3274
3275
1/2
✓ Branch 0 taken 2390 times.
✗ Branch 1 not taken.
2390 sfx(scr->secretsfx);
3276
3277
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2384 times.
2390 if(scr->flags6&fTRIGGERFPERM)
3278 {
3279
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3280
3281
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3282 {
3283
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3284 3 setflag=false;
3285 3 }
3286
3287 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3288 // which case only the screen state for mSECRET may be set below.
3289
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3290 {
3291 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3292 }
3293 6 }
3294
3295
5/6
✓ Branch 0 taken 2285 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2285 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1102 times.
✓ Branch 5 taken 1183 times.
2390 if (setflag && canPermSecret(cur_dmap, screen))
3296
2/2
✓ Branch 0 taken 720 times.
✓ Branch 1 taken 463 times.
1903 if(!(scr->flags5&fTEMPSECRETS))
3297
1/2
✓ Branch 0 taken 720 times.
✗ Branch 1 not taken.
720 setmapflag(scr, mSECRET);
3298
3299 2390 return true;
3300 4442768 }
3301
3302 14736335 void update_slopes()
3303 {
3304
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14736335 times.
14878691 for (auto& p : slopes)
3305 {
3306 142356 slope_object& s = p.second;
3307 142356 s.updateslope(); //sets old x/y poses
3308 }
3309 14736335 }
3310
3311 14329878 void update_freeform_combos()
3312 {
3313 14329878 ffscript_engine(false);
3314
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14305706 times.
14329878 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3315 {
3316 14305706 int wrap_right = world_w + 32;
3317 14305706 int wrap_bottom = world_h + 32;
3318
3319 483128592 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3320 468822886 mapscr* scr = ffc_handle.scr;
3321 468822886 ffcdata& thisffc = *ffc_handle.ffc;
3322
3323 // Combo 0?
3324
2/2
✓ Branch 0 taken 44992239 times.
✓ Branch 1 taken 423830647 times.
468822886 if(thisffc.data==0)
3325 423830647 return;
3326
3327 // Changer?
3328
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449210 times.
44992239 if(thisffc.flags&ffc_changer)
3329 543029 return;
3330
3331 // Stationary?
3332
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439366 times.
44449210 if(thisffc.flags&ffc_stationary)
3333 9844 return;
3334
3335 // Frozen because Hero's holding up an item?
3336
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44301084 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439366 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3337 138282 return;
3338
3339 // Check for changers
3340
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 if (thisffc.link==0)
3341 {
3342 442453159 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3343
2/2
✓ Branch 0 taken 14755762 times.
✓ Branch 1 taken 412940099 times.
427695861 if (ffc_handle.id == other_ffc_handle.id)
3344 14755762 return true;
3345
3346 412940099 ffcdata& otherffc = *other_ffc_handle.ffc;
3347 // Combo 0?
3348
2/2
✓ Branch 0 taken 144689583 times.
✓ Branch 1 taken 268250516 times.
412940099 if(otherffc.data==0)
3349 268250516 return true;
3350
3351 // Not a changer?
3352
2/2
✓ Branch 0 taken 140701406 times.
✓ Branch 1 taken 3988177 times.
144689583 if(!(otherffc.flags&ffc_changer))
3353 140701406 return true;
3354
3355 // Ignore this changer?
3356
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3357 845836 return true;
3358
3359
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3360 ( // At exactly the same position,
3361
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3362
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3363 //or imprecision and close enough
3364
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3365 )
3366 && //and...
3367
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3368 {
3369 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3370 3562 return false;
3371 }
3372
3373 2721195 return true;
3374 426679763 });
3375 14757298 }
3376
3377
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3378
4/4
✓ Branch 0 taken 14757298 times.
✓ Branch 1 taken 29543786 times.
✓ Branch 2 taken 14680008 times.
✓ Branch 3 taken 14863778 times.
44301084 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3379 {
3380
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681169 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863778 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3381 {
3382 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3383 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3384 97278 thisffc.x += linked_ffc->vx;
3385 97278 thisffc.y += linked_ffc->vy;
3386 97278 }
3387 else
3388 {
3389 14766500 thisffc.prev_changer_x = thisffc.x.getZLong();
3390 14766500 thisffc.prev_changer_y = thisffc.y.getZLong();
3391 14766500 thisffc.x += thisffc.vx;
3392 14766500 thisffc.y += thisffc.vy;
3393 14766500 thisffc.vx += thisffc.ax;
3394 14766500 thisffc.vy += thisffc.ay;
3395
3396
3397
2/2
✓ Branch 0 taken 444046 times.
✓ Branch 1 taken 14322454 times.
14766500 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3398 {
3399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3400
3401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3402
3403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3404
3405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3406 14322454 }
3407 }
3408 14863778 }
3409 else
3410 {
3411
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437306 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3412 76129 thisffc.delay--;
3413 }
3414
3415 // Check if the FFC's off the side of the screen
3416
3417 // Left
3418
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930619 times.
14941068 if(thisffc.x<-32)
3419 {
3420
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3421 {
3422 253 thisffc.x = wrap_right+(thisffc.x+32);
3423 253 thisffc.solid_update(false);
3424 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3425 // Re-enable previous changer
3426 253 thisffc.changer_x = -1000;
3427 253 thisffc.changer_y = -1000;
3428 253 }
3429
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3430 {
3431 69 zc_ffc_set(thisffc, 0);
3432 69 thisffc.flags&=~ffc_carryover;
3433 69 }
3434 10449 }
3435 // Right
3436
2/2
✓ Branch 0 taken 14930438 times.
✓ Branch 1 taken 181 times.
14930619 else if(thisffc.x>=wrap_right)
3437 {
3438
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3439 {
3440 128 thisffc.x = thisffc.x-wrap_right-32;
3441 128 thisffc.solid_update(false);
3442 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3443 128 thisffc.changer_x = -1000;
3444 128 thisffc.changer_y = -1000;
3445 128 }
3446 else
3447 {
3448 53 zc_ffc_set(thisffc, 0);
3449 53 thisffc.flags&=~ffc_carryover;
3450 }
3451 181 }
3452
3453 // Top
3454
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915588 times.
14941068 if(thisffc.y<-32)
3455 {
3456
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3457 {
3458 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3459 8 thisffc.solid_update(false);
3460 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3461 8 thisffc.changer_x = -1000;
3462 8 thisffc.changer_y = -1000;
3463 8 }
3464
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3465 {
3466 317 zc_ffc_set(thisffc, 0);
3467 317 thisffc.flags&=~ffc_carryover;
3468 317 }
3469 25480 }
3470 // Bottom
3471
2/2
✓ Branch 0 taken 14914744 times.
✓ Branch 1 taken 844 times.
14915588 else if(thisffc.y>=wrap_bottom)
3472 {
3473
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3474 {
3475 753 thisffc.y = thisffc.y-wrap_bottom-32;
3476 753 thisffc.solid_update(false);
3477 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3478 753 thisffc.changer_x = -1000;
3479 753 thisffc.changer_y = -1000;
3480 753 }
3481 else
3482 {
3483 91 zc_ffc_set(thisffc, 0);
3484 91 thisffc.flags&=~ffc_carryover;
3485 }
3486 844 }
3487 14941068 thisffc.solid_update();
3488 439462870 });
3489 14305706 }
3490 14329878 }
3491
3492 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3493 {
3494 for(int q = 0; q < 7; ++q)
3495 {
3496 if(layers&(1<<q)) //if layer is to be checked
3497 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3498 return true;
3499 }
3500 return false;
3501 }
3502
3503 230 optional<int> nextscr(int screen, int dir)
3504 {
3505 230 auto [m, s] = nextscr2(cur_map, screen, dir);
3506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 230 times.
230 if (m == -1) return nullopt;
3507 460 return (m<<7) + s;
3508 230 }
3509
3510 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3511 {
3512 1058 int32_t map = cur_map;
3513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : hero_screen;
3514 1058 return nextscr2(map, screen, dir);
3515 }
3516
3517 5575 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3518 {
3519 5575 screen = screen_index_direction(screen, (direction)dir);
3520
3521 // need to check for screens on other maps, 's' not valid, etc.
3522 5575 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3523
3524 // Fun fact: when a scrolling warp is triggered, this function
3525 // is never even called! - Saf
3526
2/2
✓ Branch 0 taken 3325 times.
✓ Branch 1 taken 2250 times.
6119 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3527 {
3528
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2250 switch(dir)
3529 {
3530 case up:
3531
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3532
3533 83 break;
3534
3535 case down:
3536
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3537
3538 79 break;
3539
3540 case left:
3541
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3542
3543 209 break;
3544
3545 case right:
3546
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3547
3548 173 break;
3549 }
3550
3551 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3552 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3553 544 }
3554
3555 nowarp:
3556
4/4
✓ Branch 0 taken 5511 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5399 times.
5575 if(screen<0||screen>=128)
3557 176 return {-1, -1};
3558
3559 5399 return {map, screen};
3560 5575 }
3561
3562 403 optional<int> nextscr_mi(int mi, int dir)
3563 {
3564 403 int map = mi/MAPSCRSNORMAL;
3565 403 int screen = mi%MAPSCRSNORMAL;
3566 403 auto [m, s] = nextscr2(map, screen, dir);
3567
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3568 804 return (m<<7) + s;
3569 403 }
3570
3571 2111 void bombdoor(int32_t x,int32_t y)
3572 {
3573
2/2
✓ Branch 0 taken 2091 times.
✓ Branch 1 taken 20 times.
2111 if (!is_in_world_bounds(x, y))
3574 20 return;
3575
3576 2091 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3577 2091 mapscr* scr = rpos_handle.scr;
3578 2091 int screen = scr->screen;
3579 2899 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3580 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3581
3582
12/12
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2013 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 68 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 68 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 68 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 68 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 68 times.
2091 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3583 {
3584 68 scr->door[0]=dBOMBED;
3585 68 putdoor(scr, scrollbuf, 0, dBOMBED);
3586 68 setmapflag(scr, mDOOR_UP);
3587 68 markBmap(-1, screen);
3588
3589
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 if(auto v = nextscr(screen, up))
3590 {
3591 68 setmapflag_mi(*v, mDOOR_DOWN);
3592 68 markBmap(-1,*v-(get_currdmap()<<7));
3593 68 }
3594 68 }
3595
3596
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2042 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2091 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3597 {
3598 39 scr->door[1]=dBOMBED;
3599 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3600 39 setmapflag(scr, mDOOR_DOWN);
3601 39 markBmap(-1, rpos_handle.screen);
3602
3603
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3604 {
3605 39 setmapflag_mi(*v, mDOOR_UP);
3606 39 markBmap(-1,*v-(get_currdmap()<<7));
3607 39 }
3608 39 }
3609
3610
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2024 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2091 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3611 {
3612 51 scr->door[2]=dBOMBED;
3613 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3614 51 setmapflag(scr, mDOOR_LEFT);
3615 51 markBmap(-1, rpos_handle.screen);
3616
3617
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3618 {
3619 51 setmapflag_mi(*v, mDOOR_RIGHT);
3620 51 markBmap(-1,*v-(get_currdmap()<<7));
3621 51 }
3622 51 }
3623
3624
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2005 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2091 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3625 {
3626 72 scr->door[3]=dBOMBED;
3627 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3628 72 setmapflag(scr, mDOOR_RIGHT);
3629 72 markBmap(-1, rpos_handle.screen);
3630
3631
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3632 {
3633 72 setmapflag_mi(*v, mDOOR_LEFT);
3634 72 markBmap(-1,*v-(get_currdmap()<<7));
3635 72 }
3636 72 }
3637 2111 }
3638
3639 6334592668 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3640 bool over, bool transp)
3641 {
3642 6334592668 auto& cmb = combobuf[cid];
3643
2/2
✓ Branch 0 taken 90743 times.
✓ Branch 1 taken 6334501925 times.
6334592668 if(cmb.animflags & AF_EDITOR_ONLY)
3644 90743 return;
3645
2/2
✓ Branch 0 taken 3275017955 times.
✓ Branch 1 taken 3059483970 times.
6334501925 if(over)
3646 {
3647
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3275017955 times.
3275017955 if(cmb.animflags & AF_TRANSPARENT)
3648 transp = !transp;
3649
2/2
✓ Branch 0 taken 315959260 times.
✓ Branch 1 taken 2959058695 times.
3275017955 if(transp)
3650 315959260 overcombotranslucent(dest, x, y, cid, cset, 128);
3651 2959058695 else overcombo(dest, x, y, cid, cset);
3652 3275017955 }
3653 3059483970 else putcombo(dest, x, y, cid, cset);
3654 6334592668 }
3655 6334601116 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3656 int32_t cset, byte layer, bool over, bool transp)
3657 {
3658
2/2
✓ Branch 0 taken 744495610 times.
✓ Branch 1 taken 5590105506 times.
6334601116 if (rpos != rpos_t::None)
3659 {
3660 5590105506 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3661
2/2
✓ Branch 0 taken 738365 times.
✓ Branch 1 taken 5589367141 times.
5590105506 if (plrpos != rpos_t::None)
3662 {
3663 5589367141 bool dosw = false;
3664
4/4
✓ Branch 0 taken 52309 times.
✓ Branch 1 taken 5589314832 times.
✓ Branch 2 taken 43861 times.
✓ Branch 3 taken 8448 times.
5589367141 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3665 {
3666
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3667 {
3668 draw_cmb(dest, x, y,
3669 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3670 }
3671 8448 dosw = true;
3672 8448 }
3673
4/4
✓ Branch 0 taken 31726864 times.
✓ Branch 1 taken 5557631829 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 31718416 times.
5589358693 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3674 {
3675 8448 dosw = true;
3676 8448 }
3677
2/2
✓ Branch 0 taken 5589350245 times.
✓ Branch 1 taken 16896 times.
5589367141 if (dosw)
3678 {
3679
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3680 {
3681 default: case swPOOF:
3682 break; //Nothing special here
3683 case swFLICKER:
3684 {
3685
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3686 8448 break; //Drawn this frame
3687 8448 return; //Not drawn this frame
3688 }
3689 case swRISE:
3690 {
3691 //Draw rising up
3692 y -= 8-(abs(Hero.switchhookclk-32)/4);
3693 break;
3694 }
3695 }
3696 8448 }
3697 5589358693 }
3698 5590097058 }
3699
3700 6334592668 draw_cmb(dest, x, y, cid, cset, over, transp);
3701 6334601116 }
3702
3703 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3704 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3705 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3706 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3707 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3708 //
3709 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3710 //
3711 // -16 < comboPositionX*16 + x < bitmapWidth
3712 // -16 < comboPositionY*16 + y < bitmapHeight
3713 //
3714 // The following start/end values are derived directly from the above.
3715 //
3716 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3717 39175223 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3718 {
3719 // if (bmp->clip)
3720 // {
3721 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3722 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3723 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3724 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3725 // return;
3726 // }
3727
3728
2/2
✓ Branch 0 taken 2150923 times.
✓ Branch 1 taken 37024300 times.
39175223 start_x = MAX(0, ceil((-15 - x) / 16.0));
3729
2/2
✓ Branch 0 taken 2159472 times.
✓ Branch 1 taken 37015751 times.
39175223 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3730
2/2
✓ Branch 0 taken 37794508 times.
✓ Branch 1 taken 1380715 times.
39175223 start_y = MAX(0, ceil((-15 - y) / 16.0));
3731
2/2
✓ Branch 0 taken 1669512 times.
✓ Branch 1 taken 37505711 times.
39175223 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3732 39175223 }
3733
3734 186110475 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3735 {
3736
1/2
✓ Branch 0 taken 186110475 times.
✗ Branch 1 not taken.
186110475 if(!show_ffcs) return;
3737 186110475 mapscr* scr = screen_handle.scr;
3738 186110475 mapscr* base_scr = screen_handle.base_scr;
3739
3740 186110475 y += playing_field_offset;
3741
3742 186110475 bool is_bg_layer = layer < -1;
3743
2/2
✓ Branch 0 taken 33772789 times.
✓ Branch 1 taken 152337686 times.
186110475 int real_layer = is_bg_layer ? abs(layer) : layer;
3744
2/2
✓ Branch 0 taken 186110475 times.
✓ Branch 1 taken 5554035192 times.
5740145667 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3745 {
3746
2/2
✓ Branch 0 taken 5348537496 times.
✓ Branch 1 taken 205497696 times.
5554035192 if (base_scr->ffcs[i].data == 0)
3747 5348537496 continue;
3748
4/4
✓ Branch 0 taken 37360962 times.
✓ Branch 1 taken 168136734 times.
✓ Branch 2 taken 18682962 times.
✓ Branch 3 taken 18678000 times.
205497696 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3749 18678000 continue;
3750
4/4
✓ Branch 0 taken 37360962 times.
✓ Branch 1 taken 149458734 times.
✓ Branch 2 taken 18682962 times.
✓ Branch 3 taken 18678000 times.
186819696 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3751 18678000 continue;
3752
4/4
✓ Branch 0 taken 149463696 times.
✓ Branch 1 taken 18678000 times.
✓ Branch 2 taken 18682962 times.
✓ Branch 3 taken 130780734 times.
168141696 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3753 130780734 continue;
3754
3755
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351992 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360962 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3756 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3757
3758 37358478 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3759 37358478 }
3760 186110475 }
3761 170091603 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3762 {
3763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170091603 times.
170091603 if(!show_ffcs) return;
3764 344761428 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3765 174669825 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3766 174669825 do_ffc_layer(bmp, layer, handle, 0, 0);
3767 174669825 });
3768 170091603 }
3769 74895940 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3770 {
3771 74895940 mapscr* scr = screen_handle.scr;
3772 74895940 mapscr* base_scr = screen_handle.base_scr;
3773
3774
4/4
✓ Branch 0 taken 60549812 times.
✓ Branch 1 taken 14346128 times.
✓ Branch 2 taken 14346128 times.
✓ Branch 3 taken 74895940 times.
74895940 if (type == -3 || type == -4)
3775 {
3776 28692256 y += playing_field_offset;
3777
3778
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
28692256 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3779 {
3780 if (base_scr->ffcs[i].data == 0)
3781 continue;
3782
3783 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3784 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3785
3786 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3787 }
3788 return;
3789 }
3790
3791 74895940 x -= viewport.x;
3792 74895940 y -= viewport.y - playing_field_offset;
3793
3794 74895940 bool over = true, transp = false;
3795 74895940 int layer = screen_handle.layer;
3796
3797
7/8
✓ Branch 0 taken 54641601 times.
✓ Branch 1 taken 20254339 times.
✓ Branch 2 taken 12999220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33770945 times.
✓ Branch 5 taken 20870656 times.
✓ Branch 6 taken 3020644 times.
✓ Branch 7 taken 4234475 times.
74895940 switch(type ? type : layer)
3798 {
3799 case -2: //push blocks
3800
2/2
✓ Branch 0 taken 19424817 times.
✓ Branch 1 taken 14346128 times.
33770945 if (scr)
3801 {
3802
2/2
✓ Branch 0 taken 3418767792 times.
✓ Branch 1 taken 23296697 times.
3417847673 for(int32_t i=0; i<176; i++)
3803 {
3804 3418767792 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3805
3806
10/10
✓ Branch 0 taken 3418597448 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3417125476 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3416514127 times.
✓ Branch 5 taken 611349 times.
✓ Branch 6 taken 24188284 times.
✓ Branch 7 taken 3392325843 times.
✓ Branch 8 taken 42444049 times.
✓ Branch 9 taken 16386871 times.
3455815260 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3807
6/8
✓ Branch 0 taken 3413705698 times.
✓ Branch 1 taken 21379855 times.
✓ Branch 2 taken 3413705698 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3413705698 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3376658230 times.
3416514127 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3808 {
3809
4/4
✓ Branch 0 taken 4691757 times.
✓ Branch 1 taken 685998 times.
✓ Branch 2 taken 3627 times.
✓ Branch 3 taken 4688130 times.
90265853 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3810 5377755 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3811 5377755 }
3812 3398422856 }
3813 23296697 }
3814 37642825 return;
3815
3816 case -1: //over combo
3817
1/2
✓ Branch 0 taken 20870656 times.
✗ Branch 1 not taken.
20870656 if (scr)
3818 {
3819
2/2
✓ Branch 0 taken 3673235456 times.
✓ Branch 1 taken 20870656 times.
3694106112 for(int32_t i=0; i<176; i++)
3820 {
3821
2/2
✓ Branch 0 taken 3654161080 times.
✓ Branch 1 taken 19074376 times.
3673235456 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3822 {
3823
4/4
✓ Branch 0 taken 15361523 times.
✓ Branch 1 taken 3712853 times.
✓ Branch 2 taken 21803 times.
✓ Branch 3 taken 15339720 times.
19074376 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3824 19074376 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3825 19074376 }
3826 3673235456 }
3827 20870656 }
3828 20870656 return;
3829
3830 case 1:
3831 case 4:
3832 case 5:
3833 case 6:
3834
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12999220 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12999220 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3835 {
3836
1/2
✓ Branch 0 taken 12999220 times.
✗ Branch 1 not taken.
12999220 if (scr)
3837 {
3838
2/2
✓ Branch 0 taken 11357560 times.
✓ Branch 1 taken 1641660 times.
12999220 if(base_scr->layeropacity[layer-1]!=255)
3839 1641660 transp = true;
3840 12999220 break;
3841 }
3842 }
3843 return;
3844
3845 case 2:
3846
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3020644 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3020644 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3847 {
3848
1/2
✓ Branch 0 taken 3020644 times.
✗ Branch 1 not taken.
3020644 if (scr)
3849 {
3850
2/2
✓ Branch 0 taken 2801049 times.
✓ Branch 1 taken 219595 times.
3020644 if(base_scr->layeropacity[layer-1]!=255)
3851 219595 transp = true;
3852
3853
2/2
✓ Branch 0 taken 2891734 times.
✓ Branch 1 taken 128910 times.
3020644 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3854 128910 over = false;
3855
3856 3020644 break;
3857 }
3858 }
3859 return;
3860
3861 case 3:
3862
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4234475 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4234475 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3863 {
3864
1/2
✓ Branch 0 taken 4234475 times.
✗ Branch 1 not taken.
4234475 if (scr)
3865 {
3866
2/2
✓ Branch 0 taken 4162577 times.
✓ Branch 1 taken 71898 times.
4234475 if(base_scr->layeropacity[layer-1]!=255)
3867 71898 transp = true;
3868
3869
2/2
✓ Branch 0 taken 36655 times.
✓ Branch 1 taken 60483 times.
4234475 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3870
2/2
✓ Branch 0 taken 97138 times.
✓ Branch 1 taken 4137337 times.
4234475 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3871 60483 over = false;
3872
3873 4234475 break;
3874 }
3875 }
3876 return;
3877 }
3878
3879 int start_x, end_x, start_y, end_y;
3880 20254339 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3881
2/2
✓ Branch 0 taken 20254339 times.
✓ Branch 1 taken 214721998 times.
234976337 for (int cy = start_y; cy < end_y; cy++)
3882 {
3883
2/2
✓ Branch 0 taken 3249690983 times.
✓ Branch 1 taken 214721998 times.
3464412981 for (int cx = start_x; cx < end_x; cx++)
3884 {
3885 3249690983 int i = cx + cy*16;
3886
4/4
✓ Branch 0 taken 2875683996 times.
✓ Branch 1 taken 374006987 times.
✓ Branch 2 taken 10011408 times.
✓ Branch 3 taken 2865672588 times.
3249690983 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3887 3249690983 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3888 3249690983 }
3889 214721998 }
3890 60549812 }
3891
3892 267659102 bool lenscheck(mapscr* scr, int layer)
3893 {
3894
4/4
✓ Branch 0 taken 267480154 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 267659102 times.
267659102 if(layer < 0 || layer > 6) return true;
3895
2/2
✓ Branch 0 taken 258245525 times.
✓ Branch 1 taken 9413577 times.
267659102 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3896 {
3897
2/2
✓ Branch 0 taken 208625143 times.
✓ Branch 1 taken 49620382 times.
258245525 if(!layer) return true;
3898
8/8
✓ Branch 0 taken 34741484 times.
✓ Branch 1 taken 173883659 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34482514 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34299736 times.
208625143 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3899 489872 return false;
3900 208183395 }
3901 else
3902 {
3903
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9413577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9413577 times.
9413577 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3904 return false;
3905 }
3906 217596972 return true;
3907 267480154 }
3908
3909 155396579 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3910 {
3911 155396579 bool showlayer = true;
3912 155396579 mapscr* base_scr = screen_handle.base_scr;
3913 155396579 int layer = screen_handle.layer;
3914
2/2
✓ Branch 0 taken 41893643 times.
✓ Branch 1 taken 113502936 times.
155396579 int target = type ? type : layer;
3915
3/4
✓ Branch 0 taken 113502936 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20135585 times.
✓ Branch 3 taken 21758058 times.
155396579 switch(target)
3916 {
3917 case -2:
3918
1/2
✓ Branch 0 taken 20135585 times.
✗ Branch 1 not taken.
20135585 if(!show_layer_push)
3919 showlayer = false;
3920 20135585 break;
3921
3922 case -1:
3923
1/2
✓ Branch 0 taken 21758058 times.
✗ Branch 1 not taken.
21758058 if(!show_layer_over)
3924 showlayer = false;
3925 21758058 break;
3926
3927 case 1: case 2: case 3:
3928 case 4: case 5: case 6:
3929 113502936 showlayer = show_layers[target];
3930 113502936 break;
3931 }
3932
3933
2/2
✓ Branch 0 taken 41893643 times.
✓ Branch 1 taken 113502936 times.
155396579 if(!type)
3934 {
3935
2/2
✓ Branch 0 taken 113366738 times.
✓ Branch 1 taken 136198 times.
113502936 if(!lenscheck(base_scr,layer))
3936 136198 showlayer = false;
3937 113502936 }
3938
3939
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 155260381 times.
155396579 if(showlayer)
3940 {
3941
6/6
✓ Branch 0 taken 60605935 times.
✓ Branch 1 taken 94654446 times.
✓ Branch 2 taken 20310462 times.
✓ Branch 3 taken 40295473 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 20254339 times.
155260381 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3942 {
3943 60549812 do_scrolling_layer(bmp, type, screen_handle, x, y);
3944
4/4
✓ Branch 0 taken 20254339 times.
✓ Branch 1 taken 40295473 times.
✓ Branch 2 taken 19022345 times.
✓ Branch 3 taken 1231994 times.
60549812 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3945
2/2
✓ Branch 0 taken 1231418 times.
✓ Branch 1 taken 576 times.
1232570 if(mblock2.draw(bmp,layer))
3946 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3947 60549812 }
3948 155260381 }
3949 155396579 }
3950
3951 102510921 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3952 {
3953 102510921 bool showlayer = true;
3954
3955
2/4
✓ Branch 0 taken 102510921 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 102510921 times.
102510921 if(layer >= 0 && layer <= 6)
3956 {
3957 102510921 showlayer = show_layers[layer];
3958
3959
2/2
✓ Branch 0 taken 102384319 times.
✓ Branch 1 taken 126602 times.
102510921 if(!lenscheck(origin_scr,layer))
3960 126602 showlayer = false;
3961 102510921 }
3962
3963
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102384319 times.
102510921 if (showlayer)
3964 102384319 do_primitives(bmp, layer);
3965 102510921 }
3966
3967 // Called by do_walkflags
3968 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3969 {
3970 newcombo const &c = combobuf[cmbdat];
3971
3972 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3973
3974 int32_t xx = x-xofs;
3975 int32_t yy = y+playing_field_offset-yofs;
3976
3977 int32_t bridgedetected = 0;
3978
3979 for(int32_t i=0; i<4; i++)
3980 {
3981 int32_t tx=((i&2)<<2)+xx - viewport.x;
3982 int32_t ty=((i&1)<<3)+yy - viewport.y;
3983 int32_t tx2=((i&2)<<2)+x - viewport.x;
3984 int32_t ty2=((i&1)<<3)+y - viewport.y;
3985 for (int32_t j = lyr-1; j <= 1; j++)
3986 {
3987 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3988 {
3989 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3990 {
3991 bridgedetected |= (1<<i);
3992 }
3993 }
3994 else
3995 {
3996 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
3997 {
3998 bridgedetected |= (1<<i);
3999 }
4000 }
4001 }
4002 if ((bridgedetected & (1<<i)))
4003 {
4004 if (i >= 3) break;
4005 else continue;
4006 }
4007 bool doladdercheck = true;
4008
4009 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4010 {
4011 for(int32_t k=0; k<8; k+=2)
4012 for(int32_t j=0; j<8; j+=2)
4013 if(((k+j)/2)%2)
4014 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4015 }
4016 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4017 {
4018 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4019 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4020 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4021 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4022 }
4023
4024 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4025 {
4026 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4027 {
4028 for(int32_t k=0; k<8; k+=2)
4029 for(int32_t j=0; j<8; j+=2)
4030 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4031 }
4032 else
4033 {
4034 int32_t color = makecol(178,36,36);
4035
4036 if(isstepable(cmbdat)&& (!doladdercheck))
4037 color=makecol(165,105,8);
4038 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4039 color=makecol(170,170,170);
4040
4041 rectfill(dest,tx,ty,tx+7,ty+7,color);
4042 }
4043 }
4044 }
4045
4046 // Draw damage combos
4047 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4048 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4049 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4050
4051 if(dmg)
4052 {
4053 int32_t color = makecol(255,255,0);
4054 if (bridgedetected <= 0)
4055 {
4056 for(int32_t k=0; k<16; k+=2)
4057 for(int32_t j=0; j<16; j+=2)
4058 if(((k+j)/2)%2)
4059 {
4060 int32_t x0 = x - viewport.x;
4061 int32_t y0 = y - viewport.y;
4062 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4063 }
4064 }
4065 else
4066 {
4067 for(int32_t i=0; i<4; i++)
4068 {
4069 if (!(bridgedetected & (1<<i)))
4070 {
4071 int32_t tx=((i&2)<<2)+x - viewport.x;
4072 int32_t ty=((i&1)<<3)+y - viewport.y;
4073 for(int32_t k=0; k<8; k+=2)
4074 for(int32_t j=0; j<8; j+=2)
4075 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4076 }
4077 }
4078 }
4079 }
4080 }
4081 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4082 {
4083 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4084 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4085 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4086 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4087 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4088 newcombo const &c = combobuf[cmbdat];
4089
4090 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4091
4092 int32_t xx = x-viewport.x;
4093 int32_t yy = y+playing_field_offset-viewport.y;
4094
4095 int32_t bridgedetected = 0;
4096
4097 // Draw damage combos
4098 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4099
4100 for(int32_t i=0; i<4; i++)
4101 {
4102 int32_t tx=((i&2)<<2)+xx;
4103 int32_t ty=((i&1)<<3)+yy;
4104 int32_t tx2=((i&2)<<2)+x;
4105 int32_t ty2=((i&1)<<3)+y;
4106 for (int32_t m = lyr-1; m <= 1; m++)
4107 {
4108 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4109 {
4110 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4111 {
4112 bridgedetected |= (1<<i);
4113 }
4114 }
4115 else
4116 {
4117 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4118 {
4119 bridgedetected |= (1<<i);
4120 }
4121 }
4122 }
4123 if ((bridgedetected & (1<<i)))
4124 continue;
4125 bool doladdercheck = true;
4126
4127 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4128 {
4129 for(int32_t k=0; k<8; k+=2)
4130 for(int32_t j=0; j<8; j+=2)
4131 if(((k+j)/2)%2)
4132 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4133 }
4134 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4135 {
4136 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4137 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4138 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4139 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4140 }
4141
4142 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4143 {
4144 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4145 {
4146 for(int32_t k=0; k<8; k+=2)
4147 for(int32_t j=0; j<8; j+=2)
4148 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4149 }
4150 else
4151 {
4152 ALLEGRO_COLOR* color = &col_solid;
4153
4154 if(isstepable(cmbdat)&& (!doladdercheck))
4155 color=&col_stepable;
4156 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4157 color=&col_lhook;
4158
4159 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4160 }
4161 }
4162
4163 if(dmg)
4164 {
4165 for(int32_t k=0; k<8; k+=2)
4166 for(int32_t j=0; j<8; j+=2)
4167 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4168 }
4169 }
4170 }
4171
4172 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4173 {
4174 newcombo const &c = combobuf[cmbdat];
4175
4176 int32_t xx = x-xofs-viewport.x;
4177 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4178
4179 for(int32_t i=0; i<4; i++)
4180 {
4181 int32_t tx=((i&2)<<2)+xx;
4182 int32_t ty=((i&1)<<3)+yy;
4183
4184 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4185 {
4186 int32_t color = vc(10);
4187
4188 rectfill(dest,tx,ty,tx+7,ty+7,color);
4189 }
4190 }
4191 }
4192 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4193 {
4194 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4195 newcombo const &c = combobuf[cmbdat];
4196
4197 int32_t xx = x-viewport.x;
4198 int32_t yy = y+playing_field_offset-viewport.y;
4199
4200 for(int32_t i=0; i<4; i++)
4201 {
4202 int32_t tx=((i&2)<<2)+xx;
4203 int32_t ty=((i&1)<<3)+yy;
4204
4205 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4206 {
4207 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4208 }
4209 }
4210 }
4211
4212 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4213 {
4214 for(auto cx = 0; cx < 256; cx += 16)
4215 {
4216 for(auto cy = 0; cy < 176; cy += 16)
4217 {
4218 if(isSVLadder(cx,cy))
4219 {
4220 auto nx = cx+x, ny = cy+y;
4221 if(cy && !isSVLadder(cx,cy-16))
4222 line(dest,nx,ny,nx+15,ny,c);
4223 rectfill(dest,nx,ny,nx+3,ny+15,c);
4224 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4225 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4226 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4227 }
4228 else if(isSVPlatform(cx,cy))
4229 {
4230 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4231 }
4232 }
4233 }
4234 }
4235 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4236 {
4237 for(auto cx = 0; cx < 256; cx += 16)
4238 {
4239 for(auto cy = 0; cy < 176; cy += 16)
4240 {
4241 if(isSVLadder(cx,cy))
4242 {
4243 auto nx = cx+x, ny = cy+y;
4244 if(cy && !isSVLadder(cx,cy-16))
4245 al_draw_line(nx,ny,nx+15,ny,c,1);
4246 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4247 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4248 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4249 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4250 }
4251 else if(isSVPlatform(cx,cy))
4252 {
4253 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4254 }
4255 }
4256 }
4257 }
4258
4259 // Walkflags L4 cheat
4260 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4261 {
4262 if (!show_walkflags)
4263 return;
4264
4265 start_info_bmp();
4266
4267 mapscr* scr = screen_handles[0].scr;
4268 for(int32_t i=0; i<176; i++)
4269 {
4270 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4271 }
4272
4273 for(int32_t k=0; k<2; k++)
4274 {
4275 scr = screen_handles[k + 1].scr;
4276
4277 if (scr)
4278 {
4279 for(int32_t i=0; i<176; i++)
4280 {
4281 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4282 }
4283 }
4284 }
4285
4286 end_info_bmp();
4287 }
4288
4289 void do_walkflags(int32_t x, int32_t y)
4290 {
4291 if (!show_walkflags)
4292 return;
4293
4294 x += -viewport.x;
4295 y += playing_field_offset - viewport.y;
4296
4297 start_info_bmp();
4298
4299 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4300 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4301 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4302
4303 end_info_bmp();
4304 }
4305
4306 // Effectflags L4 cheat
4307 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4308 {
4309 if(show_effectflags)
4310 {
4311 start_info_bmp();
4312
4313 for(int32_t i=0; i<176; i++)
4314 {
4315 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4316 }
4317
4318 end_info_bmp();
4319 }
4320 }
4321
4322 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4323 {
4324 272141 int map = scr->map;
4325 272141 int screen = scr->screen;
4326
4327
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4328 {
4329 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4330
2/2
✓ Branch 0 taken 780869 times.
✓ Branch 1 taken 1124118 times.
1904987 if (!scr->is_valid()) continue;
4331
4332
2/2
✓ Branch 0 taken 137432944 times.
✓ Branch 1 taken 780869 times.
138213813 for(int32_t q = 0; q < 176; ++q)
4333 {
4334 137432944 newcombo const& cmb = combobuf[scr->data[q]];
4335
2/2
✓ Branch 0 taken 136828325 times.
✓ Branch 1 taken 604619 times.
137432944 if(cmb.type == cTORCH)
4336 {
4337 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4338 604619 }
4339 137432944 }
4340 780869 }
4341 272141 }
4342
4343 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4344 {
4345 272141 word c = scr->numFFC();
4346
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4347 {
4348 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4349
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4350 {
4351 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4352 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4353 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4354 14808 }
4355 537406 }
4356 272141 }
4357
4358 struct nearby_screen_t
4359 {
4360 int screen;
4361 int offx;
4362 int offy;
4363 screen_handles_t screen_handles;
4364 };
4365 typedef std::vector<nearby_screen_t> nearby_screens_t;
4366
4367 15410919 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4368 {
4369 15410919 nearby_screens_t nearby_screens;
4370
4371 15410919 mapscr* base_scr = origin_scr;
4372
1/2
✓ Branch 0 taken 15410919 times.
✗ Branch 1 not taken.
15410919 auto& nearby_screen = nearby_screens.emplace_back();
4373 15410919 nearby_screen.screen = cur_screen;
4374
1/2
✓ Branch 0 taken 15410919 times.
✗ Branch 1 not taken.
15410919 nearby_screen.screen_handles = create_screen_handles(base_scr);
4375
4376 15410919 return nearby_screens;
4377
1/2
✓ Branch 0 taken 15410919 times.
✗ Branch 1 not taken.
15410919 }
4378
4379 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4380 {
4381 48296 nearby_screens_t nearby_screens;
4382
4383
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4384
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4385
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4386
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4387
4388
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4389
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4390
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4391
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4392
4393
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4394 {
4395
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4396 {
4397 169672 int screen = cur_screen + x + y*16;
4398
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4399
4400
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4401
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4402
4403
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4404
4405
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4406 169672 nearby_screen.screen = screen;
4407 169672 nearby_screen.offx = offx;
4408 169672 nearby_screen.offy = offy;
4409
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4410 169672 }
4411 79928 }
4412
4413 48296 return nearby_screens;
4414
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4415
4416 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4417 {
4418 3658 nearby_screens_t nearby_screens;
4419
4420
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4421
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4422
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4423
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4424
4425
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4426
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4427
4428
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4429 {
4430
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4431 {
4432 18600 int screen = -1;
4433 mapscr* base_scr;
4434 int offx, offy;
4435
4436 18600 mapscr* maze_scr = maze_state.scr;
4437 18600 int maze_screen = maze_scr->screen;
4438
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4439
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4440 18600 int maze_screen_dx = x - maze_screen_x;
4441 18600 int maze_screen_dy = y - maze_screen_y;
4442 18600 int exitdir = maze_scr->exitdir;
4443
4444 bool should_draw_maze_screen;
4445
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4446 {
4447 9548 should_draw_maze_screen = true;
4448 9548 }
4449 else
4450 {
4451 9052 should_draw_maze_screen = true;
4452
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4453
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4454
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4455 }
4456
4457
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4458 {
4459 16048 screen = maze_state.scr->screen;
4460 16048 base_scr = maze_state.scr;
4461
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4462 16048 }
4463
4464
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4465 {
4466 2552 screen = cur_screen + x + y*16;
4467
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4468
4469
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4470
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4471
4472
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4473 2552 }
4474
4475
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4476 18600 nearby_screen.screen = screen;
4477 18600 nearby_screen.offx = offx;
4478 18600 nearby_screen.offy = offy;
4479
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4480 18600 }
4481 7308 }
4482
4483 3658 return nearby_screens;
4484
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4485
4486 15462873 static nearby_screens_t get_nearby_screens()
4487 {
4488
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15453659 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15462873 if (maze_state.active && maze_state.loopy)
4489 3658 return get_nearby_screens_smooth_maze();
4490
4491
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15410919 times.
15459215 if (is_in_scrolling_region())
4492 48296 return get_nearby_screens_scrolling_region();
4493
4494 15410919 return get_nearby_screens_non_scrolling_region();
4495 15462873 }
4496
4497 201038842 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4498 {
4499
2/2
✓ Branch 0 taken 202823444 times.
✓ Branch 1 taken 201038842 times.
403862286 for (auto& nearby_screen : nearby_screens)
4500 202823444 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4501 201038842 }
4502
4503 123702984 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4504 {
4505
2/2
✓ Branch 0 taken 15462873 times.
✓ Branch 1 taken 108240111 times.
123702984 if(layer != msgstr_layer) return;
4506
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 if(!dest) dest = framebuf;
4507
4508
2/2
✓ Branch 0 taken 678885 times.
✓ Branch 1 taken 14783988 times.
15462873 if(!(msg_bg_display_buf->clip))
4509 {
4510 678885 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4511 678885 }
4512
4513
2/2
✓ Branch 0 taken 678885 times.
✓ Branch 1 taken 14783988 times.
15462873 if(!(msg_portrait_display_buf->clip))
4514 {
4515 678885 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4516 678885 }
4517
4518
2/2
✓ Branch 0 taken 692292 times.
✓ Branch 1 taken 14770581 times.
15462873 if(!(msg_txt_display_buf->clip))
4519 {
4520 692292 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4521 692292 }
4522 123702984 }
4523
4524 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4525
4526 61851492 static void set_draw_screen_clip(BITMAP* bmp)
4527 {
4528 61851492 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4529 61851492 }
4530
4531 45891699 void draw_screen(bool showhero, bool runGeneric)
4532 {
4533 45891699 clear_info_bmp();
4534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45891699 times.
45891699 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4535 {
4536 FFCore.doScriptMenuDraws();
4537 return;
4538 }
4539
4540
2/2
✓ Branch 0 taken 31026387 times.
✓ Branch 1 taken 14865312 times.
45891699 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4541
4542 45891699 clear_bitmap(framebuf);
4543 45891699 clear_clip_rect(framebuf);
4544
4545 45891699 int32_t cmby2=0;
4546
4547 // Draw some background layers
4548 45891699 clear_bitmap(scrollbuf);
4549
4550 45891699 auto nearby_screens = get_nearby_screens();
4551
4552 // Handle layer 2/3 possibly being background layers.
4553
1/2
✓ Branch 0 taken 45891699 times.
✗ Branch 1 not taken.
61490890 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4554 15599191 mapscr* base_scr = screen_handles[0].base_scr;
4555
2/2
✓ Branch 0 taken 15471909 times.
✓ Branch 1 taken 127282 times.
15599191 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4556 127282 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4557 15599191 });
4558
4559
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 45764417 times.
45891699 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4560 {
4561
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 do_layer_primitives(scrollbuf, 2);
4562
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 particles.draw(scrollbuf, true, 2);
4563 127282 }
4564
2/2
✓ Branch 0 taken 15462873 times.
✓ Branch 1 taken 30428826 times.
45891699 _do_current_ffc_layer(scrollbuf, -2);
4565
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15335591 times.
15462873 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4566
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 draw_msgstr(2, scrollbuf);
4567
4568
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4569 15599191 mapscr* base_scr = screen_handles[0].base_scr;
4570
2/2
✓ Branch 0 taken 15506531 times.
✓ Branch 1 taken 92660 times.
15599191 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4571 92660 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4572 15599191 });
4573
4574
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15370213 times.
15462873 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4575 {
4576
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 do_layer_primitives(scrollbuf, 3);
4577
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 particles.draw(scrollbuf, true, 3);
4578 92660 }
4579
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(scrollbuf, -3);
4580
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15370213 times.
15462873 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4581
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 draw_msgstr(3, scrollbuf);
4582
4583 // Draw the main combo screens ("layer 0").
4584
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4585 15599191 mapscr* base_scr = screen_handles[0].base_scr;
4586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15599191 times.
15599191 if (lenscheck(base_scr, 0))
4587 {
4588 15599191 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4589 15599191 }
4590 15599191 });
4591
4592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15462873 times.
15462873 if (lenscheck(hero_scr, 0))
4593 {
4594
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 14996824 times.
15462873 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4595
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4596
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4597 15462873 }
4598
4599 // Lens hints, then primitives, then particles.
4600
6/10
✓ Branch 0 taken 15452844 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15452844 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15452844 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15462873 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4601 {
4602
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4603
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4604 5876 }
4605
4606
2/4
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15462873 times.
✗ Branch 3 not taken.
15462873 if(show_layers[0] && lenscheck(hero_scr,0))
4607
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_primitives(scrollbuf, 0);
4608
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 particles.draw(scrollbuf, true, 0);
4609
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(scrollbuf, 0);
4610
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 draw_msgstr(0, scrollbuf);
4611
4612
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 set_draw_screen_clip(scrollbuf);
4613
4614
2/2
✓ Branch 0 taken 15119614 times.
✓ Branch 1 taken 343259 times.
15462873 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4615 {
4616
4/4
✓ Branch 0 taken 15117744 times.
✓ Branch 1 taken 1870 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15029680 times.
30202926 if(showhero &&
4617
4/6
✓ Branch 0 taken 15117744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15083312 times.
✓ Branch 3 taken 34432 times.
✓ Branch 4 taken 15083312 times.
✗ Branch 5 not taken.
15117744 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4618 {
4619
3/4
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34432 times.
88064 if(Hero.getAction()==climbcovertop)
4620 {
4621 34432 cmby2=16;
4622 34432 }
4623
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4624 {
4625 53632 cmby2=-16;
4626 53632 }
4627
4628
1/2
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
88064 decorations.draw2(scrollbuf,true);
4629
1/2
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
88064 Hero.draw(scrollbuf);
4630
1/2
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
88064 decorations.draw(scrollbuf,true);
4631
2/4
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88064 times.
✗ Branch 3 not taken.
88064 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4632
2/4
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88064 times.
✗ Branch 3 not taken.
88064 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4633
4634
3/6
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88064 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88064 times.
✗ Branch 5 not taken.
88064 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4635
3/6
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88064 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88064 times.
✗ Branch 5 not taken.
88064 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4636
4637
4/6
✓ Branch 0 taken 88064 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88064 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15168 times.
✓ Branch 5 taken 72896 times.
88064 if(int32_t(Hero.getX())&15)
4638 {
4639
3/6
✓ Branch 0 taken 15168 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15168 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15168 times.
✗ Branch 5 not taken.
15168 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4640
3/6
✓ Branch 0 taken 15168 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15168 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15168 times.
✗ Branch 5 not taken.
15168 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4641 15168 }
4642 88064 }
4643 15119614 }
4644
4645
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4646 15599191 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4647 15599191 });
4648
4649
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_layer_primitives(scrollbuf, 1);
4650
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 particles.draw(scrollbuf, true, 1);
4651
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(scrollbuf, 1);
4652
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 draw_msgstr(1, scrollbuf);
4653
4654 // Handle layer 2 NOT being used as background layers.
4655
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4656 15599191 mapscr* base_scr = screen_handles[0].base_scr;
4657
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15471909 times.
15599191 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4658 15471909 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4659 15599191 });
4660
4661
2/2
✓ Branch 0 taken 15335591 times.
✓ Branch 1 taken 127282 times.
15462873 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4662 {
4663
1/2
✓ Branch 0 taken 15335591 times.
✗ Branch 1 not taken.
15335591 do_layer_primitives(scrollbuf, 2);
4664
1/2
✓ Branch 0 taken 15335591 times.
✗ Branch 1 not taken.
15335591 particles.draw(scrollbuf, true, 2);
4665 15335591 }
4666
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(scrollbuf, 2);
4667
2/2
✓ Branch 0 taken 15335591 times.
✓ Branch 1 taken 127282 times.
15462873 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4668
1/2
✓ Branch 0 taken 15335591 times.
✗ Branch 1 not taken.
15335591 draw_msgstr(2, scrollbuf);
4669
4670
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4671
4672
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15119614 times.
15462873 if(get_qr(qr_LAYER12UNDERCAVE))
4673 {
4674
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4675
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4676 {
4677 if(Hero.getAction()==climbcovertop)
4678 {
4679 cmby2=16;
4680 }
4681 else if(Hero.getAction()==climbcoverbottom)
4682 {
4683 cmby2=-16;
4684 }
4685
4686 decorations.draw2(scrollbuf,true);
4687 Hero.draw(scrollbuf);
4688 decorations.draw(scrollbuf,true);
4689 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4690 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4691
4692 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4693 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4694
4695 if(int32_t(Hero.getX())&15)
4696 {
4697 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4698 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4699 }
4700 }
4701 343259 }
4702
4703
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 14996824 times.
15462873 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4704 {
4705
1/2
✓ Branch 0 taken 14996824 times.
✗ Branch 1 not taken.
30129966 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4706 15133142 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4707
2/2
✓ Branch 0 taken 14402156 times.
✓ Branch 1 taken 730986 times.
15133142 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4708 {
4709 730986 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4710 730986 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4711 730986 }
4712 15133142 });
4713
4714
1/2
✓ Branch 0 taken 14996824 times.
✗ Branch 1 not taken.
14996824 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4715 14996824 }
4716
4717 // Show walkflags cheat
4718
2/4
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15462873 times.
15462873 if (show_walkflags || show_effectflags)
4719 {
4720 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4721 do_walkflags(screen_handles, offx, offy);
4722 do_effectflags(screen_handles[0].base_scr, offx, offy);
4723 });
4724
4725 do_walkflags(0, 0);
4726 }
4727
4728
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4729
4730 // Lens hints, doors etc.
4731
4/8
✓ Branch 0 taken 15452844 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15452844 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15452844 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15462873 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4732 {
4733
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4734 {
4735
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4736
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4737 4153 }
4738
4739
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4740
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4741 10029 }
4742
4743 // Blit those layers onto framebuf
4744
4745
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 set_draw_screen_clip(framebuf);
4746
4747
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4748
4749 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4750 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4751
4752 // Draw the subscreen, without clipping
4753
2/2
✓ Branch 0 taken 9174619 times.
✓ Branch 1 taken 6288254 times.
15462873 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4754 {
4755 9174619 bool dotime = false;
4756
4/6
✓ Branch 0 taken 9174619 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3336088 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3336088 times.
✗ Branch 5 not taken.
9174619 if (replay_version_check(22)) dotime = game->should_show_time();
4757
1/2
✓ Branch 0 taken 9174619 times.
✗ Branch 1 not taken.
9174619 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4758 9174619 }
4759
4760 // Draw some sprites onto framebuf
4761
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 set_clip_rect(framebuf,0,0,256,232);
4762
4763
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15363377 times.
15462873 if(!(pricesdisplaybuf->clip))
4764 {
4765
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4766 99496 }
4767
4768
5/6
✓ Branch 0 taken 15417247 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15410919 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15462873 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4769 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4770
4771
8/10
✓ Branch 0 taken 15461003 times.
✓ Branch 1 taken 1870 times.
✓ Branch 2 taken 15461003 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15426571 times.
✓ Branch 5 taken 34432 times.
✓ Branch 6 taken 15426571 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15372939 times.
✓ Branch 9 taken 53632 times.
15462873 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4772 {
4773
1/2
✓ Branch 0 taken 15372939 times.
✗ Branch 1 not taken.
15372939 Hero.draw_under(framebuf);
4774
4775
3/4
✓ Branch 0 taken 15372939 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 140041 times.
✓ Branch 3 taken 15232898 times.
15372939 if(Hero.isSwimming())
4776 {
4777
1/2
✓ Branch 0 taken 140041 times.
✗ Branch 1 not taken.
140041 decorations.draw2(framebuf,true);
4778
1/2
✓ Branch 0 taken 140041 times.
✗ Branch 1 not taken.
140041 Hero.draw(framebuf);
4779
1/2
✓ Branch 0 taken 140041 times.
✗ Branch 1 not taken.
140041 decorations.draw(framebuf,true);
4780 140041 }
4781 15372939 }
4782
4783
2/2
✓ Branch 0 taken 25967 times.
✓ Branch 1 taken 15436906 times.
15462873 if(drawguys)
4784 {
4785
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 13454232 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
15436906 if(get_qr(qr_NOFLICKER) || (frame&1))
4786 {
4787 // Just clips sprites if in a repeating, smooth maze.
4788
2/2
✓ Branch 0 taken 14436107 times.
✓ Branch 1 taken 9214 times.
14445321 bool do_clip = maze_state.active && maze_state.loopy;
4789
4790
3/4
✓ Branch 0 taken 23503469 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9058148 times.
✓ Branch 3 taken 14445321 times.
23503469 for(int32_t i=0; i<Ewpns.Count(); i++)
4791 {
4792
3/4
✓ Branch 0 taken 9058148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8860205 times.
9058148 if(((weapon *)Ewpns.spr(i))->behind)
4793
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4794 9058148 }
4795
1/2
✓ Branch 0 taken 14445321 times.
✗ Branch 1 not taken.
14445321 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4796
4797
3/4
✓ Branch 0 taken 19106128 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4660807 times.
✓ Branch 3 taken 14445321 times.
19106128 for(int32_t i=0; i<Lwpns.Count(); i++)
4798 {
4799
3/4
✓ Branch 0 taken 4660807 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4657602 times.
4660807 if(((weapon *)Lwpns.spr(i))->behind)
4800
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4801 4660807 }
4802
1/2
✓ Branch 0 taken 14445321 times.
✗ Branch 1 not taken.
14445321 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4803
4804
6/6
✓ Branch 0 taken 9708457 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8360157 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14445321 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4805 {
4806
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9030510 times.
9034168 if (do_clip)
4807
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4808 else
4809
1/2
✓ Branch 0 taken 9030510 times.
✗ Branch 1 not taken.
9030510 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4810 9034168 }
4811
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14441663 times.
14445321 if (do_clip)
4812
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4813 else
4814
1/2
✓ Branch 0 taken 14441663 times.
✗ Branch 1 not taken.
14441663 guys.draw(framebuf,true);
4815
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14441663 times.
14445321 if (do_clip)
4816 {
4817 3658 int maze_screen = maze_state.scr->screen;
4818
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4819
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4820 3658 }
4821
1/2
✓ Branch 0 taken 14445321 times.
✗ Branch 1 not taken.
14445321 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4822
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14441663 times.
14445321 if (do_clip)
4823
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4824
4825
1/2
✓ Branch 0 taken 14445321 times.
✗ Branch 1 not taken.
14445321 chainlinks.draw(framebuf,true);
4826
1/2
✓ Branch 0 taken 14445321 times.
✗ Branch 1 not taken.
14445321 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4827 //Lwpns.draw(framebuf,true);
4828
4829
3/4
✓ Branch 0 taken 23503469 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9058148 times.
✓ Branch 3 taken 14445321 times.
23503469 for(int32_t i=0; i<Ewpns.Count(); i++)
4830 {
4831
3/4
✓ Branch 0 taken 9058148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8860205 times.
✓ Branch 3 taken 197943 times.
9058148 if(!((weapon *)Ewpns.spr(i))->behind)
4832
2/4
✓ Branch 0 taken 8860205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8860205 times.
✗ Branch 3 not taken.
8860205 Ewpns.spr(i)->draw(framebuf);
4833 9058148 }
4834
1/2
✓ Branch 0 taken 14445321 times.
✗ Branch 1 not taken.
14445321 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4835
4836
3/4
✓ Branch 0 taken 19106128 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4660807 times.
✓ Branch 3 taken 14445321 times.
19106128 for(int32_t i=0; i<Lwpns.Count(); i++)
4837 {
4838
3/4
✓ Branch 0 taken 4660807 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4657602 times.
✓ Branch 3 taken 3205 times.
4660807 if(!((weapon *)Lwpns.spr(i))->behind)
4839
2/4
✓ Branch 0 taken 4657602 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4657602 times.
✗ Branch 3 not taken.
4657602 Lwpns.spr(i)->draw(framebuf);
4840 4660807 }
4841
1/2
✓ Branch 0 taken 14445321 times.
✗ Branch 1 not taken.
14445321 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4842
4843
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14441663 times.
14445321 if (do_clip)
4844
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4845 else
4846
1/2
✓ Branch 0 taken 14441663 times.
✗ Branch 1 not taken.
14441663 items.draw(framebuf,true);
4847
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14441663 times.
14445321 if (do_clip)
4848 {
4849 3658 int maze_screen = maze_state.scr->screen;
4850
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4851
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4852 3658 }
4853
1/2
✓ Branch 0 taken 14445321 times.
✗ Branch 1 not taken.
14445321 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4854
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14441663 times.
14445321 if (do_clip)
4855
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4856 14445321 }
4857 else
4858 {
4859
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4860 {
4861
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4862
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4863 505372 }
4864
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4865
4866
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4867 {
4868
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
4869 Lwpns.spr(i)->draw(framebuf);
4870 231146 }
4871
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4872
4873
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4874 {
4875
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4876 228620 }
4877
4878
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(framebuf,false);
4879
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4880
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(framebuf,false);
4881
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4882 //Lwpns.draw(framebuf,false);
4883
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(framebuf,false);
4884
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4885
4886
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4887 {
4888
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4889 {
4890
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4891 496727 }
4892 505372 }
4893
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4894
4895
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4896 {
4897
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
4898 {
4899
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(framebuf);
4900 231146 }
4901 231146 }
4902
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4903 }
4904
4905
1/2
✓ Branch 0 taken 15436906 times.
✗ Branch 1 not taken.
15436906 guys.draw2(framebuf,true);
4906 15436906 }
4907
4908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15462873 times.
15462873 if(mirror_portal.destdmap > -1)
4909 mirror_portal.draw(framebuf);
4910
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 portals.draw(framebuf,true);
4911
4912
8/10
✓ Branch 0 taken 15461003 times.
✓ Branch 1 taken 1870 times.
✓ Branch 2 taken 15461003 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15426571 times.
✓ Branch 5 taken 34432 times.
✓ Branch 6 taken 15426571 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15372939 times.
✓ Branch 9 taken 53632 times.
15462873 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4913 {
4914
2/2
✓ Branch 0 taken 14913306 times.
✓ Branch 1 taken 459633 times.
15372939 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4915 {
4916
1/2
✓ Branch 0 taken 14913306 times.
✗ Branch 1 not taken.
14913306 mblock2.draw(framebuf,-1);
4917
1/2
✓ Branch 0 taken 14913306 times.
✗ Branch 1 not taken.
14913306 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4918 14913306 }
4919
3/4
✓ Branch 0 taken 15372939 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232898 times.
✓ Branch 3 taken 140041 times.
15372939 if(!Hero.isSwimming())
4920 {
4921
8/12
✓ Branch 0 taken 15232898 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232898 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15213728 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15213728 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15213728 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15231528 times.
15232898 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4922 {
4923
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15214413 times.
15232898 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4924 18485 }
4925
4926
6/8
✓ Branch 0 taken 15232898 times.
✓ Branch 1 taken 15214413 times.
✓ Branch 2 taken 15232898 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232898 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15218834 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4927 {
4928
1/2
✓ Branch 0 taken 15218834 times.
✗ Branch 1 not taken.
15218834 decorations.draw2(framebuf,true);
4929
1/2
✓ Branch 0 taken 15218834 times.
✗ Branch 1 not taken.
15218834 Hero.draw(framebuf);
4930
1/2
✓ Branch 0 taken 15218834 times.
✗ Branch 1 not taken.
15218834 decorations.draw(framebuf,true);
4931 15218834 }
4932 15232898 }
4933 15372939 }
4934
4935
3/4
✓ Branch 0 taken 54630400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39167527 times.
✓ Branch 3 taken 15462873 times.
54630400 for(int32_t i=0; i<guys.Count(); i++)
4936 {
4937
3/4
✓ Branch 0 taken 39167527 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15880929 times.
✓ Branch 3 taken 23286598 times.
39167527 if(((enemy*)guys.spr(i))->family == eeWALK)
4938 {
4939
3/4
✓ Branch 0 taken 15880929 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15873634 times.
15880929 if(((eStalfos*)guys.spr(i))->hashero)
4940 {
4941
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4942 7295 }
4943 15880929 }
4944
4945
3/4
✓ Branch 0 taken 39167527 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 500182 times.
✓ Branch 3 taken 38667345 times.
39167527 if(((enemy*)guys.spr(i))->family == eeWALLM)
4946 {
4947
3/4
✓ Branch 0 taken 500182 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 498853 times.
500182 if(((eWallM*)guys.spr(i))->hashero)
4948 {
4949
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4950 1329 }
4951 500182 }
4952
4953
11/20
✓ Branch 0 taken 39167527 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39167527 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39167527 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39167527 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39167527 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39167527 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39167527 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39167527 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39167527 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37824833 times.
39167527 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4954 {
4955 //Jumping enemies in front of Hero.
4956
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4957 1342694 }
4958
1/2
✓ Branch 0 taken 39167527 times.
✗ Branch 1 not taken.
39167527 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4959 39167527 }
4960
4961 // Draw some layers onto framebuf
4962
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 set_draw_screen_clip(framebuf);
4963
5/6
✓ Branch 0 taken 15417247 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15410919 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15462873 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4964 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4965
4966 // Handle layer 3 NOT being used as background layers.
4967
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4968 15599191 mapscr* base_scr = screen_handles[0].base_scr;
4969
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15506531 times.
15599191 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4970 15506531 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4971 15599191 });
4972
4973
2/2
✓ Branch 0 taken 15370213 times.
✓ Branch 1 taken 92660 times.
15462873 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4974 {
4975
1/2
✓ Branch 0 taken 15370213 times.
✗ Branch 1 not taken.
15370213 do_layer_primitives(framebuf, 3);
4976
1/2
✓ Branch 0 taken 15370213 times.
✗ Branch 1 not taken.
15370213 particles.draw(framebuf, true, 3);
4977 15370213 }
4978
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(framebuf, 3);
4979
2/2
✓ Branch 0 taken 15370213 times.
✓ Branch 1 taken 92660 times.
15462873 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4980
1/2
✓ Branch 0 taken 15370213 times.
✗ Branch 1 not taken.
15370213 draw_msgstr(3);
4981
4982
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4983 15599191 do_layer(framebuf, 0, screen_handles[4], offx, offy);
4984 15599191 });
4985
4986
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_layer_primitives(framebuf, 4);
4987
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 particles.draw(framebuf, true, 4);
4988
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(framebuf, 4);
4989
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 draw_msgstr(4);
4990
4991
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4992 15599191 do_layer(framebuf, -1, screen_handles[0], offx, offy);
4993
2/2
✓ Branch 0 taken 14323436 times.
✓ Branch 1 taken 1275755 times.
15599191 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
4994 {
4995 1275755 do_layer(framebuf, -1, screen_handles[1], offx, offy);
4996 1275755 do_layer(framebuf, -1, screen_handles[2], offx, offy);
4997 1275755 }
4998 15599191 });
4999
5000
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
5001
5002 // Draw some flying sprites onto framebuf
5003
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 clear_clip_rect(framebuf);
5004
5/6
✓ Branch 0 taken 15417247 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15410919 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15462873 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5005 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5006
5007 //Jumping Hero and jumping enemies are drawn on this layer.
5008
5/8
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15462873 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15462873 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 15448809 times.
15462873 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5009 {
5010
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(framebuf,false);
5011
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(framebuf);
5012
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(framebuf,true);
5013
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
5014
5015
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5016 {
5017
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5018 {
5019
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
5020 239 }
5021 2742 }
5022
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
5023
5024
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(framebuf,false);
5025 14064 }
5026
5027
5/6
✓ Branch 0 taken 3288982 times.
✓ Branch 1 taken 12173891 times.
✓ Branch 2 taken 44084556 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 31910665 times.
✓ Branch 5 taken 12173891 times.
47373538 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5028 {
5029
13/22
✓ Branch 0 taken 31910665 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31910665 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27043187 times.
✓ Branch 5 taken 4867478 times.
✓ Branch 6 taken 27043187 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27043187 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27043187 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27043187 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27043187 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27043187 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27043187 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27036619 times.
31910665 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5030 {
5031
2/4
✓ Branch 0 taken 4874046 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4874046 times.
✗ Branch 3 not taken.
4874046 guys.spr(i)->draw(framebuf);
5032 4874046 }
5033 44084556 }
5034 else
5035 {
5036
3/4
✓ Branch 0 taken 10545844 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288982 times.
10545844 for(int32_t i=0; i<guys.Count(); i++)
5037 {
5038
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5039 {
5040
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
5041 1662516 }
5042 7256862 }
5043 }
5044
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
5045
5046 // Draw the Moving Fairy above layer 3
5047
3/4
✓ Branch 0 taken 18591845 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3128972 times.
✓ Branch 3 taken 15462873 times.
18591845 for(int32_t i=0; i<items.Count(); i++)
5048
6/8
✓ Branch 0 taken 3128972 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69653 times.
✓ Branch 3 taken 3059319 times.
✓ Branch 4 taken 69653 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 59939 times.
✓ Branch 7 taken 9714 times.
3188911 if(itemsbuf[items.spr(i)->id].family == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5049
2/4
✓ Branch 0 taken 59939 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 59939 times.
✗ Branch 3 not taken.
59939 items.spr(i)->draw(framebuf);
5050
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
5051
5052 // Draw some layers onto framebuf
5053
5054
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 set_draw_screen_clip(framebuf);
5055
5056
2/2
✓ Branch 0 taken 15448521 times.
✓ Branch 1 taken 14352 times.
15462873 if (lightbeam_present)
5057 {
5058 14352 color_map = &trans_table2;
5059
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5060
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
5061 else
5062
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
5063 14352 color_map = &trans_table;
5064 14352 }
5065
5066
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5067 15599191 do_layer(framebuf, 0, screen_handles[5], offx, offy);
5068 15599191 });
5069
5070
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_layer_primitives(framebuf, 5);
5071
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 particles.draw(framebuf, true, 5);
5072
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(framebuf, 5);
5073
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 draw_msgstr(5);
5074
5075
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
5076
5077
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
5078
5079
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5080 15599191 do_layer(framebuf, 0, screen_handles[6], offx, offy);
5081 15599191 });
5082
5083
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 do_layer_primitives(framebuf, 6);
5084
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 particles.draw(framebuf, true, 6);
5085
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(framebuf, 6);
5086
5087 15462873 bool any_dark = false;
5088
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5089 15599191 mapscr* base_scr = screen_handles[0].scr;
5090 15599191 any_dark |= is_dark(base_scr);
5091 15599191 });
5092
5093 // Handle low drawn darkness
5094
4/4
✓ Branch 0 taken 1269419 times.
✓ Branch 1 taken 14193454 times.
✓ Branch 2 taken 1025648 times.
✓ Branch 3 taken 243771 times.
15462873 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5095 {
5096
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5097 250005 mapscr* base_scr = screen_handles[0].scr;
5098 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5099 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5100 250005 });
5101
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
5102
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
5103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5104 250005 mapscr* base_scr = screen_handles[0].scr;
5105
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
5106 {
5107 4730 offy += playing_field_offset;
5108 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5109 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5110 4730 }
5111 250005 });
5112 243771 }
5113
5114 //Darkroom if under the subscreen
5115
6/6
✓ Branch 0 taken 1269419 times.
✓ Branch 1 taken 14193454 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 446135 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15462873 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5116 {
5117
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5118
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5120 {
5121 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5122 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5123 }
5124
5125 231780 color_map = &trans_table2;
5126
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5127 {
5128
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5129
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5130
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5131 144 }
5132 else
5133 {
5134
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5135
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5136 }
5137 231780 color_map = &trans_table;
5138
5139
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5140
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5141 231780 }
5142
5143
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15417247 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15462873 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5144 {
5145 draw_lens_over();
5146 --lensclk;
5147 }
5148
5149 // Draw some text on framebuf
5150
5151
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 set_clip_rect(framebuf,0,0,256,232);
5152
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5153
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 draw_msgstr(6);
5154
5155 // Draw the subscreen, without clipping
5156
2/2
✓ Branch 0 taken 6288254 times.
✓ Branch 1 taken 9174619 times.
15462873 if(get_qr(qr_SUBSCREENOVERSPRITES))
5157 {
5158
2/4
✓ Branch 0 taken 6288254 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6288254 times.
✗ Branch 3 not taken.
6288254 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5159
5160 // Draw primitives over subscren
5161
1/2
✓ Branch 0 taken 6288254 times.
✗ Branch 1 not taken.
6288254 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5162 6288254 }
5163
5164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15462873 times.
15462873 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5165 draw_msgstr(6);
5166
5167 // Handle high-drawn darkness
5168
6/6
✓ Branch 0 taken 1269419 times.
✓ Branch 1 taken 14193454 times.
✓ Branch 2 taken 446135 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 434144 times.
15462873 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5169 {
5170
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5171
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5173 {
5174 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5175 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5176 }
5177
5178 11991 color_map = &trans_table2;
5179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5180 {
5181 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5182 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5183 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5184 }
5185 else
5186 {
5187
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5188
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5189 }
5190 11991 color_map = &trans_table;
5191
5192
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5193
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5194 11991 }
5195
5196
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 _do_current_ffc_layer(framebuf, 7);
5197
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 draw_msgstr(7);
5198
5199
1/2
✓ Branch 0 taken 15462873 times.
✗ Branch 1 not taken.
15462873 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5200
3/4
✓ Branch 0 taken 14865312 times.
✓ Branch 1 taken 597561 times.
✓ Branch 2 taken 14865312 times.
✗ Branch 3 not taken.
15462873 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5201 76320525 }
5202
5203 // TODO: separate setting door data and drawing door
5204 27902 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5205 {
5206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27902 times.
27902 if (type > 8) return;
5207
5208 27902 int32_t d=scr->door_combo_set;
5209
5210
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15515 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12387 times.
27902 switch(type)
5211 {
5212 case dt_wall:
5213 case dt_walk:
5214 if(!even_walls)
5215 break;
5216 [[fallthrough]];
5217 case dt_pass:
5218
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11351 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12387 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5219 1036 break;
5220 [[fallthrough]];
5221 case dt_lock:
5222 case dt_shut:
5223 case dt_boss:
5224 case dt_olck:
5225 case dt_osht:
5226 case dt_obos:
5227 case dt_bomb:
5228
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7197 times.
✓ Branch 2 taken 6740 times.
✓ Branch 3 taken 6291 times.
✓ Branch 4 taken 6638 times.
26866 switch(side)
5229 {
5230 case up:
5231 7197 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5232 7197 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5233 7197 scr->sflag[pos] = 0;
5234 7197 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5235 7197 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5236 7197 scr->sflag[pos+1] = 0;
5237 7197 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5238 7197 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5239 7197 scr->sflag[pos+16] = 0;
5240 7197 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5241 7197 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5242 7197 scr->sflag[pos+16+1] = 0;
5243
5244
2/2
✓ Branch 0 taken 5381 times.
✓ Branch 1 taken 1816 times.
7197 if(redraw)
5245 {
5246 3632 putcombo(dest,(pos&15)<<4,pos&0xF0,
5247 1816 DoorComboSets[d].doorcombo_u[type][0],
5248 1816 DoorComboSets[d].doorcset_u[type][0]);
5249 3632 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5250 1816 DoorComboSets[d].doorcombo_u[type][1],
5251 1816 DoorComboSets[d].doorcset_u[type][1]);
5252 1816 }
5253
5254 7197 break;
5255
5256 case down:
5257 6740 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5258 6740 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5259 6740 scr->sflag[pos] = 0;
5260 6740 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5261 6740 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5262 6740 scr->sflag[pos+1] = 0;
5263 6740 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5264 6740 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5265 6740 scr->sflag[pos+16] = 0;
5266 6740 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5267 6740 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5268 6740 scr->sflag[pos+16+1] = 0;
5269
5270
2/2
✓ Branch 0 taken 5422 times.
✓ Branch 1 taken 1318 times.
6740 if(redraw)
5271 {
5272 2636 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5273 1318 DoorComboSets[d].doorcombo_d[type][2],
5274 1318 DoorComboSets[d].doorcset_d[type][2]);
5275 2636 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5276 1318 DoorComboSets[d].doorcombo_d[type][3],
5277 1318 DoorComboSets[d].doorcset_d[type][3]);
5278 1318 }
5279
5280 6740 break;
5281
5282 case left:
5283 6291 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5284 6291 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5285 6291 scr->sflag[pos] = 0;
5286 6291 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5287 6291 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5288 6291 scr->sflag[pos+1] = 0;
5289 6291 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5290 6291 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5291 6291 scr->sflag[pos+16] = 0;
5292 6291 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5293 6291 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5294 6291 scr->sflag[pos+16+1] = 0;
5295 6291 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5296 6291 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5297 6291 scr->sflag[pos+32] = 0;
5298 6291 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5299 6291 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5300 6291 scr->sflag[pos+32+1] = 0;
5301
5302
2/2
✓ Branch 0 taken 4813 times.
✓ Branch 1 taken 1478 times.
6291 if(redraw)
5303 {
5304 2956 putcombo(dest,(pos&15)<<4,pos&0xF0,
5305 1478 DoorComboSets[d].doorcombo_l[type][0],
5306 1478 DoorComboSets[d].doorcset_l[type][0]);
5307 2956 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5308 1478 DoorComboSets[d].doorcombo_l[type][2],
5309 1478 DoorComboSets[d].doorcset_l[type][2]);
5310 2956 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5311 1478 DoorComboSets[d].doorcombo_l[type][4],
5312 1478 DoorComboSets[d].doorcset_l[type][4]);
5313 1478 }
5314
5315 6291 break;
5316
5317 case right:
5318 6638 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5319 6638 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5320 6638 scr->sflag[pos] = 0;
5321 6638 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5322 6638 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5323 6638 scr->sflag[pos+1] = 0;
5324 6638 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5325 6638 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5326 6638 scr->sflag[pos+16] = 0;
5327 6638 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5328 6638 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5329 6638 scr->sflag[pos+16+1] = 0;
5330 6638 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5331 6638 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5332 6638 scr->sflag[pos+32] = 0;
5333 6638 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5334 6638 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5335 6638 scr->sflag[pos+32+1] = 0;
5336
5337
2/2
✓ Branch 0 taken 4995 times.
✓ Branch 1 taken 1643 times.
6638 if(redraw)
5338 {
5339 3286 putcombo(dest,(pos&15)<<4,pos&0xF0,
5340 1643 DoorComboSets[d].doorcombo_r[type][0],
5341 1643 DoorComboSets[d].doorcset_r[type][0]);
5342 3286 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5343 1643 DoorComboSets[d].doorcombo_r[type][2],
5344 1643 DoorComboSets[d].doorcset_r[type][2]);
5345 3286 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5346 1643 DoorComboSets[d].doorcombo_r[type][4],
5347 1643 DoorComboSets[d].doorcset_r[type][4]);
5348 1643 }
5349
5350 6638 break;
5351 }
5352
5353 26866 break;
5354
5355 default:
5356 break;
5357 }
5358 27902 }
5359
5360 703043 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5361 {
5362 703043 int32_t door_combo_set = scr->door_combo_set;
5363 703043 int32_t x = (pos&15)<<4;
5364 703043 int32_t y = (pos&0xF0);
5365 703043 int32_t d = door_combo_set;
5366 703043 x += offx;
5367 703043 y += offy;
5368
5369
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 160487 times.
✓ Branch 2 taken 178006 times.
✓ Branch 3 taken 195319 times.
✓ Branch 4 taken 169231 times.
703043 switch(side)
5370 {
5371 case up:
5372 320974 overcombo2(dest,x,y,
5373 160487 DoorComboSets[d].bombdoorcombo_u[0],
5374 160487 DoorComboSets[d].bombdoorcset_u[0]);
5375 320974 overcombo2(dest,x+16,y,
5376 160487 DoorComboSets[d].bombdoorcombo_u[1],
5377 160487 DoorComboSets[d].bombdoorcset_u[1]);
5378 160487 break;
5379
5380 case down:
5381 356012 overcombo2(dest,x,y,
5382 178006 DoorComboSets[d].bombdoorcombo_d[0],
5383 178006 DoorComboSets[d].bombdoorcset_d[0]);
5384 356012 overcombo2(dest,x+16,y,
5385 178006 DoorComboSets[d].bombdoorcombo_d[1],
5386 178006 DoorComboSets[d].bombdoorcset_d[1]);
5387 178006 break;
5388
5389 case left:
5390 390638 overcombo2(dest,x,y,
5391 195319 DoorComboSets[d].bombdoorcombo_l[0],
5392 195319 DoorComboSets[d].bombdoorcset_l[0]);
5393 390638 overcombo2(dest,x,y+16,
5394 195319 DoorComboSets[d].bombdoorcombo_l[1],
5395 195319 DoorComboSets[d].bombdoorcset_l[1]);
5396 390638 overcombo2(dest,x,y+16,
5397 195319 DoorComboSets[d].bombdoorcombo_l[2],
5398 195319 DoorComboSets[d].bombdoorcset_l[2]);
5399 195319 break;
5400
5401 case right:
5402 338462 overcombo2(dest,x,y,
5403 169231 DoorComboSets[d].bombdoorcombo_r[0],
5404 169231 DoorComboSets[d].bombdoorcset_r[0]);
5405 338462 overcombo2(dest,x,y+16,
5406 169231 DoorComboSets[d].bombdoorcombo_r[1],
5407 169231 DoorComboSets[d].bombdoorcset_r[1]);
5408 338462 overcombo2(dest,x,y+16,
5409 169231 DoorComboSets[d].bombdoorcombo_r[2],
5410 169231 DoorComboSets[d].bombdoorcset_r[2]);
5411 169231 break;
5412 }
5413 703043 }
5414
5415 47040 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5416 {
5417
7/8
✓ Branch 0 taken 46932 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 46932 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22706 times.
✓ Branch 5 taken 24226 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22176 times.
47040 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5418 24864 return;
5419
5420 int32_t doortype;
5421
5422
10/12
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 654 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12337 times.
✓ Branch 5 taken 907 times.
✓ Branch 6 taken 1539 times.
✓ Branch 7 taken 3174 times.
✓ Branch 8 taken 1685 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 64 times.
✓ Branch 11 taken 1130 times.
22176 switch(door)
5423 {
5424 case dWALL:
5425 doortype=dt_wall;
5426 break;
5427
5428 case dWALK:
5429 doortype=dt_walk;
5430 break;
5431
5432 case dOPEN:
5433 12337 doortype=dt_pass;
5434 12337 break;
5435
5436 case dLOCKED:
5437 907 doortype=dt_lock;
5438 907 break;
5439
5440 case dUNLOCKED:
5441 1539 doortype=dt_olck;
5442 1539 break;
5443
5444 case dSHUTTER:
5445
3/4
✓ Branch 0 taken 2768 times.
✓ Branch 1 taken 406 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2768 times.
3174 if(screenscrolling && ((HeroDir()^1)==side))
5446 {
5447 doortype=dt_osht;
5448 get_screen_state(scr->screen).open_doors = -4;
5449 break;
5450 }
5451
5452 [[fallthrough]];
5453 case d1WAYSHUTTER:
5454 3688 doortype=dt_shut;
5455 3688 break;
5456
5457 case dOPENSHUTTER:
5458 1685 doortype=dt_osht;
5459 1685 break;
5460
5461 case dBOSS:
5462 172 doortype=dt_boss;
5463 172 break;
5464
5465 case dOPENBOSS:
5466 64 doortype=dt_obos;
5467 64 break;
5468
5469 case dBOMBED:
5470 1130 doortype=dt_bomb;
5471 1130 break;
5472
5473 default:
5474 654 return;
5475 }
5476
5477
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5575 times.
✓ Branch 2 taken 5729 times.
✓ Branch 3 taken 5051 times.
✓ Branch 4 taken 5167 times.
21522 switch(side)
5478 {
5479 case up:
5480 5575 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5481 5575 break;
5482
5483 case down:
5484 5729 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5485 5729 break;
5486
5487 case left:
5488 5051 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5489 5051 break;
5490
5491 case right:
5492 5167 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5493 5167 break;
5494 }
5495 47040 }
5496
5497 6471 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5498 {
5499 /*
5500 #define dWALL 0 // 000 0
5501 #define dBOMB 6 // 011 0
5502 #define 8 // 100 0
5503 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5504 */
5505
5506
7/8
✓ Branch 0 taken 6471 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6467 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6384 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6376 times.
6471 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5507 91 return;
5508
5509 int32_t doortype;
5510
5511
8/12
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1522 times.
✓ Branch 8 taken 3935 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 230 times.
6380 switch(door)
5512 {
5513 case dWALL:
5514 doortype=dt_wall;
5515 break;
5516
5517 case dWALK:
5518 doortype=dt_walk;
5519 break;
5520
5521 case dOPEN:
5522 50 doortype=dt_pass;
5523 50 break;
5524
5525 case dLOCKED:
5526 doortype=dt_lock;
5527 break;
5528
5529 case dUNLOCKED:
5530 362 doortype=dt_olck;
5531 362 break;
5532
5533 case dSHUTTER:
5534
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1522 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1522 if(screenscrolling && ((HeroDir()^1)==side))
5535 {
5536 doortype=dt_osht;
5537 get_screen_state(cur_screen).open_doors = -4;
5538 break;
5539 }
5540
5541 [[fallthrough]];
5542 case d1WAYSHUTTER:
5543 1748 doortype=dt_shut;
5544 1748 break;
5545
5546 case dOPENSHUTTER:
5547 3935 doortype=dt_osht;
5548 3935 break;
5549
5550 case dBOSS:
5551 4 doortype=dt_boss;
5552 4 break;
5553
5554 case dOPENBOSS:
5555 51 doortype=dt_obos;
5556 51 break;
5557
5558 case dBOMBED:
5559 230 doortype=dt_bomb;
5560 230 break;
5561
5562 default:
5563 return;
5564 }
5565
5566
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1852 times.
✓ Branch 2 taken 1354 times.
✓ Branch 3 taken 1503 times.
✓ Branch 4 taken 1671 times.
6380 switch(side)
5567 {
5568 case up:
5569
2/2
✓ Branch 0 taken 1784 times.
✓ Branch 1 taken 68 times.
1852 switch(door)
5570 {
5571 case dBOMBED:
5572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
136 if(redraw)
5573 {
5574 68 over_door(scr,dest,39,side,0,0);
5575 68 }
5576 [[fallthrough]];
5577 default:
5578 1852 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5579 1852 break;
5580 }
5581
5582 1852 break;
5583
5584 case down:
5585
2/2
✓ Branch 0 taken 1315 times.
✓ Branch 1 taken 39 times.
1354 switch(door)
5586 {
5587 case dBOMBED:
5588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5589 {
5590 39 over_door(scr,dest,135,side,0,0);
5591 39 }
5592 [[fallthrough]];
5593 default:
5594 1354 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5595 1354 break;
5596 }
5597
5598 1354 break;
5599
5600 case left:
5601
2/2
✓ Branch 0 taken 1452 times.
✓ Branch 1 taken 51 times.
1503 switch(door)
5602 {
5603 case dBOMBED:
5604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5605 {
5606 51 over_door(scr,dest,66,side,0,0);
5607 51 }
5608 [[fallthrough]];
5609 default:
5610 1503 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5611 1503 break;
5612 }
5613
5614 1503 break;
5615
5616 case right:
5617
2/2
✓ Branch 0 taken 1599 times.
✓ Branch 1 taken 72 times.
1671 switch(door)
5618 {
5619 case dBOMBED:
5620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5621 {
5622 72 over_door(scr,dest,77,side,0,0);
5623 72 }
5624 [[fallthrough]];
5625 default:
5626 1671 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5627 1671 break;
5628 }
5629
5630 1671 break;
5631 }
5632 6471 }
5633
5634 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5635 {
5636
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5637 {
5638 586 putcombo(dest,x, y, combo, cset);
5639 586 }
5640 586 }
5641
5642 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5643 {
5644
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5645 {
5646 219 overcombo(dest,x, y, combo, cset);
5647 219 }
5648 293 }
5649
5650 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5651 {
5652 125 int32_t d = scr->door_combo_set;
5653
5654
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5655 {
5656 case up:
5657 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5658 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5659 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5660 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5661 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5662 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5663 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5664 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5665 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5666 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5667 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5668 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5669 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5670 43 DoorComboSets[d].bombdoorcombo_u[0],
5671 43 DoorComboSets[d].bombdoorcset_u[0]);
5672 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5673 43 DoorComboSets[d].bombdoorcombo_u[1],
5674 43 DoorComboSets[d].bombdoorcset_u[1]);
5675 43 break;
5676
5677 case down:
5678 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5679 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5680 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5681 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5682 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5683 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5684 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5685 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5686 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5687 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5688 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5689 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5690 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5691 39 DoorComboSets[d].bombdoorcombo_d[0],
5692 39 DoorComboSets[d].bombdoorcset_d[0]);
5693 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5694 39 DoorComboSets[d].bombdoorcombo_d[1],
5695 39 DoorComboSets[d].bombdoorcset_d[1]);
5696 39 break;
5697
5698 case left:
5699 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5700 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5701 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5702 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5703 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5704 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5705 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5706 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5707 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5708 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5709 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5710 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5711 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5712 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5713 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5714 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5715 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5716 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5717 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5718 6 DoorComboSets[d].bombdoorcombo_l[0],
5719 6 DoorComboSets[d].bombdoorcset_l[0]);
5720 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5721 6 DoorComboSets[d].bombdoorcombo_l[1],
5722 6 DoorComboSets[d].bombdoorcset_l[1]);
5723 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5724 6 DoorComboSets[d].bombdoorcombo_l[2],
5725 6 DoorComboSets[d].bombdoorcset_l[2]);
5726 6 break;
5727
5728 case right:
5729 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5730 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5731 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5732 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5733 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5734 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5735 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5736 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5737 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5738 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5739 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5740 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5741 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5742 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5743 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5744 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5745 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5746 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5747 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5748 37 DoorComboSets[d].bombdoorcombo_r[0],
5749 37 DoorComboSets[d].bombdoorcset_r[0]);
5750 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5751 37 DoorComboSets[d].bombdoorcombo_r[1],
5752 37 DoorComboSets[d].bombdoorcset_r[1]);
5753 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5754 37 DoorComboSets[d].bombdoorcombo_r[2],
5755 37 DoorComboSets[d].bombdoorcset_r[2]);
5756 37 break;
5757 }
5758 125 }
5759
5760 5325844 void openshutters(mapscr* scr)
5761 {
5762 5325844 bool opened_door = false;
5763
2/2
✓ Branch 0 taken 5325844 times.
✓ Branch 1 taken 21303376 times.
26629220 for(int32_t i=0; i<4; i++)
5764
2/2
✓ Branch 0 taken 21299441 times.
✓ Branch 1 taken 3935 times.
21307311 if(scr->door[i]==dSHUTTER)
5765 {
5766 3935 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5767 3935 scr->door[i]=dOPENSHUTTER;
5768 3935 opened_door = true;
5769 3935 }
5770
5771 5325844 auto& combo_cache = combo_caches::shutter;
5772 2001378016 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5773
3/4
✓ Branch 0 taken 1994441497 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1610668 times.
✗ Branch 3 not taken.
1996052172 if (!combo_cache.minis[handle.data()].shutter)
5774 1996052165 return;
5775
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5776 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5777 });
5778 1996052172 });
5779
5780
2/2
✓ Branch 0 taken 5323127 times.
✓ Branch 1 taken 2717 times.
5325844 if(opened_door)
5781 2717 sfx(WAV_DOOR,128);
5782 5325844 }
5783
5784 15041884 void clear_darkroom_bitmaps()
5785 {
5786 15041884 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5787 15041884 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5788 15041884 }
5789
5790 15953728 bool is_dark(const mapscr* scr)
5791 {
5792 15953728 bool dark = scr->flags&fDARK;
5793
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 15950006 times.
15953728 if (region_is_lit) return !dark;
5794 15950006 return dark;
5795 15953728 }
5796
5797 39077 bool scrolling_is_dark(const mapscr* scr)
5798 {
5799 39077 bool dark = scr->flags&fDARK;
5800
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39075 times.
39077 if (scrolling_region_is_lit) return !dark;
5801 39075 return dark;
5802 39077 }
5803
5804 36572 bool is_any_dark()
5805 {
5806 36572 bool dark = false;
5807 74400 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5808 37828 dark |= (bool)(is_dark(scr));
5809 37828 });
5810 36572 return dark;
5811 }
5812
5813 415 static mapscr prev_origin_scrs[7];
5814 415 static std::set<int> loadscr_ffc_script_ids_to_remove;
5815
5816 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5817 {
5818 mapscr* base_scr = screens[0];
5819 mapscr* previous_scr = &prev_origin_scrs[0];
5820
5821 for (int i = 0; i < 176; i++)
5822 {
5823 if (base_scr->data[i] == 0)
5824 {
5825 base_scr->data[i] = previous_scr->data[i];
5826 base_scr->sflag[i] = previous_scr->sflag[i];
5827 base_scr->cset[i] = previous_scr->cset[i];
5828 }
5829 }
5830
5831 for (int i = 0; i < 6; i++)
5832 {
5833 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5834 {
5835 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5836 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5837
5838 for (int j = 0; j < 176; j++)
5839 {
5840 if (TheMaps[lm].data[j] == 0)
5841 {
5842 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5843 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5844 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5845 }
5846 }
5847 }
5848 }
5849
5850 for (int i = 1; i <= 6; i++)
5851 {
5852 mapscr* scr = screens[i];
5853 previous_scr = &prev_origin_scrs[i];
5854
5855 if (scr->layermap[i] > 0)
5856 {
5857 for (int y = 0; y < 11; y++)
5858 {
5859 for (int x = 0; x < 16; x++)
5860 {
5861 int c = y*16+x;
5862
5863 if (scr->data[c]==0)
5864 {
5865 scr->data[c] = previous_scr->data[c];
5866 scr->sflag[c] = previous_scr->sflag[c];
5867 scr->cset[c] = previous_scr->cset[c];
5868 }
5869 }
5870 }
5871 }
5872 }
5873 }
5874
5875 36912 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5876 {
5877 36912 std::vector<mapscr*> screens;
5878
5879
1/2
✓ Branch 0 taken 36912 times.
✗ Branch 1 not taken.
36912 const mapscr* source = get_canonical_scr(cur_map, screen);
5880
2/4
✓ Branch 0 taken 36912 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36912 times.
✗ Branch 3 not taken.
36912 mapscr* base_scr = new mapscr(*source);
5881 36912 temporary_screens[screen*7] = base_scr;
5882
1/2
✓ Branch 0 taken 36912 times.
✗ Branch 1 not taken.
36912 screens.push_back(base_scr);
5883
5884 36912 base_scr->valid |= mVALID; // layer 0 is always valid
5885
5886
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35668 times.
36912 if (screen == cur_screen)
5887 35668 origin_scr = base_scr;
5888
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35668 times.
36912 if (screen == hero_screen)
5889 35668 hero_scr = prev_hero_scr = base_scr;
5890
5891
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36793 times.
36912 if (source->script > 0)
5892
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5893
5894
2/2
✓ Branch 0 taken 36912 times.
✓ Branch 1 taken 221472 times.
258384 for (int i = 0; i < 6; i++)
5895 {
5896
2/2
✓ Branch 0 taken 172818 times.
✓ Branch 1 taken 48654 times.
221472 if(source->layermap[i]>0)
5897 {
5898
3/6
✓ Branch 0 taken 48654 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48654 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48654 times.
✗ Branch 5 not taken.
48654 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5899 48654 layer_scr->map = cur_map;
5900 48654 layer_scr->screen = screen;
5901
1/2
✓ Branch 0 taken 48654 times.
✗ Branch 1 not taken.
48654 screens.push_back(layer_scr);
5902 48654 }
5903 else
5904 {
5905
1/2
✓ Branch 0 taken 172818 times.
✗ Branch 1 not taken.
172818 mapscr* layer_scr = new mapscr();
5906 172818 layer_scr->map = cur_map;
5907 172818 layer_scr->screen = screen;
5908
1/2
✓ Branch 0 taken 172818 times.
✗ Branch 1 not taken.
172818 screens.push_back(layer_scr);
5909 }
5910 221472 temporary_screens[screen*7+i+1] = screens[i+1];
5911 221472 }
5912
5913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36912 times.
36912 if (screen_overlay)
5914 handle_screen_overlay(screens);
5915
5916
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36768 times.
36912 if (ffc_overlay)
5917 {
5918 144 mapscr* previous_scr = &prev_origin_scrs[0];
5919
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5920
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5921 {
5922
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5923 {
5924
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5925 274 ffc.screen_spawned = screen;
5926
5927
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5928
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5930 {
5931 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5932 }
5933 274 }
5934 4608 }
5935 144 }
5936
5937
1/2
✓ Branch 0 taken 36912 times.
✗ Branch 1 not taken.
1135809 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5938
1/2
✓ Branch 0 taken 36912 times.
✗ Branch 1 not taken.
36912 int num_ffcs = base_scr->numFFC();
5939
2/2
✓ Branch 0 taken 1098897 times.
✓ Branch 1 taken 36912 times.
1135809 for (word i = 0; i < num_ffcs; i++)
5940 {
5941 1098897 base_scr->ffcs[i].screen_spawned = screen;
5942
1/2
✓ Branch 0 taken 1098897 times.
✗ Branch 1 not taken.
1098897 base_scr->ffcs[i].x += offx;
5943
1/2
✓ Branch 0 taken 1098897 times.
✗ Branch 1 not taken.
1098897 base_scr->ffcs[i].y += offy;
5944 1098897 }
5945 36912 }
5946
5947 36912 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5948 {
5949 36912 mapscr* base_scr = get_scr(screen);
5950 36912 int mi = mapind(cur_map, screen);
5951
5952 // Apply perm secrets, if applicable.
5953
2/2
✓ Branch 0 taken 11389 times.
✓ Branch 1 taken 25523 times.
36912 if (canPermSecret(dmap, screen))
5954 {
5955
2/2
✓ Branch 0 taken 23003 times.
✓ Branch 1 taken 2520 times.
25523 if(game->maps[mi] & mSECRET) // if special stuff done before
5956 {
5957 2520 reveal_hidden_stairs(base_scr, screen, false);
5958 2520 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5959 2520 }
5960
2/2
✓ Branch 0 taken 25520 times.
✓ Branch 1 taken 3 times.
25523 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5961 {
5962
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5963 {
5964 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5965
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5966 {
5967 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5968
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5969 {
5970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5971 {
5972 3 layer_scr->data[pos] += 1;
5973 3 }
5974 3 }
5975 3696 }
5976 21 }
5977 3 }
5978 25523 }
5979
5980 36912 auto screen_handles = create_screen_handles(base_scr);
5981
5982 36912 int destlvl = DMaps[dmap].level;
5983 36912 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
5984 36912 toggle_gswitches_load(screen_handles);
5985
5986 36912 bool should_check_for_state_things = (screen < 0x80);
5987
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 36006 times.
36912 if (should_check_for_state_things)
5988 {
5989
2/2
✓ Branch 0 taken 35636 times.
✓ Branch 1 taken 370 times.
36006 if (game->maps[mi]&mLOCKBLOCK)
5990 370 remove_lockblocks(screen_handles);
5991
2/2
✓ Branch 0 taken 35952 times.
✓ Branch 1 taken 54 times.
36006 if (game->maps[mi]&mBOSSLOCKBLOCK)
5992 54 remove_bosslockblocks(screen_handles);
5993
2/2
✓ Branch 0 taken 35850 times.
✓ Branch 1 taken 156 times.
36006 if (game->maps[mi]&mCHEST)
5994 156 remove_chests(screen_handles);
5995
1/2
✓ Branch 0 taken 36006 times.
✗ Branch 1 not taken.
36006 if (game->maps[mi]&mLOCKEDCHEST)
5996 remove_lockedchests(screen_handles);
5997
2/2
✓ Branch 0 taken 35995 times.
✓ Branch 1 taken 11 times.
36006 if (game->maps[mi]&mBOSSCHEST)
5998 11 remove_bosschests(screen_handles);
5999
6000 36006 clear_xdoors_mi(screen_handles, mi, true);
6001 36006 clear_xstatecombos_mi(screen_handles, mi, true);
6002 36006 }
6003
6004 // check doors
6005
2/2
✓ Branch 0 taken 25522 times.
✓ Branch 1 taken 11390 times.
36912 if (isdungeon(dmap, screen))
6006 {
6007
2/2
✓ Branch 0 taken 45560 times.
✓ Branch 1 taken 11390 times.
56950 for(int32_t i=0; i<4; i++)
6008 {
6009 45560 int32_t door=base_scr->door[i];
6010
6011
5/5
✓ Branch 0 taken 5268 times.
✓ Branch 1 taken 36015 times.
✓ Branch 2 taken 2355 times.
✓ Branch 3 taken 227 times.
✓ Branch 4 taken 1695 times.
45560 switch(door)
6012 {
6013 case d1WAYSHUTTER:
6014 case dSHUTTER:
6015
3/4
✓ Branch 0 taken 1685 times.
✓ Branch 1 taken 3583 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1685 times.
5268 if ((ldir^1)==i && screen == hero_screen)
6016 {
6017 1685 base_scr->door[i]=dOPENSHUTTER;
6018 1685 }
6019
6020 5268 get_screen_state(screen).open_doors = -4;
6021 5268 break;
6022
6023 case dLOCKED:
6024
3/4
✓ Branch 0 taken 2355 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1459 times.
✓ Branch 3 taken 896 times.
2355 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6025 {
6026 1459 base_scr->door[i]=dUNLOCKED;
6027 1459 }
6028
6029 2355 break;
6030
6031 case dBOSS:
6032
3/4
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 59 times.
✓ Branch 3 taken 168 times.
227 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6033 {
6034 59 base_scr->door[i]=dOPENBOSS;
6035 59 }
6036
6037 227 break;
6038
6039 case dBOMB:
6040
3/4
✓ Branch 0 taken 1695 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1079 times.
✓ Branch 3 taken 616 times.
1695 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6041 {
6042 1079 base_scr->door[i]=dBOMBED;
6043 1079 }
6044
6045 1695 break;
6046 }
6047
6048 45560 update_door(base_scr, i, base_scr->door[i]);
6049
6050
4/4
✓ Branch 0 taken 41019 times.
✓ Branch 1 taken 4541 times.
✓ Branch 2 taken 727 times.
✓ Branch 3 taken 40292 times.
45560 if(door==dSHUTTER||door==d1WAYSHUTTER)
6051 {
6052 5268 base_scr->door[i]=door;
6053 5268 }
6054 45560 }
6055 11390 }
6056
6057
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36775 times.
36912 if (!(base_scr->flags3 & fCYCLEONINIT))
6058 36775 return;
6059
6060
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6061 {
6062
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
6063 {
6064 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6065
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6066 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6067
6068
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6069 {
6070 90464 int32_t c=layerscreen->data[i];
6071
6072 // New screen flag: Cycle Combos At Screen Init
6073
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6074 {
6075 65 int32_t r = 0;
6076
6077
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6078 {
6079 84 newcombo const& cmb = combobuf[c];
6080 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6082 84 layerscreen->data[i] = cid;
6083
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6085 84 c = layerscreen->data[i];
6086 }
6087 65 }
6088 90464 }
6089 514 }
6090 959 }
6091 36912 }
6092
6093 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6094 //
6095 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6096 // the game, etc...)
6097 //
6098 // Note: for regions, only the initial screen load calls this function. Simply walking between
6099 // screens in the same region does not use this, because every screen in a region is loaded into
6100 // temporary memory up front.
6101 //
6102 // If scr >= 0x80, `hero_screen` will be saved to `home_screen` and also be loaded into
6103 // `special_warp_return_scr`.
6104 //
6105 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6106 // on all layers (but only where the new screen has a 0 combo).
6107 //
6108 // TODO: loadscr should set curdmap, but currently callers do that.
6109 35668 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6110 {
6111 35668 zapp_reporting_set_tag("screen", screen);
6112
2/2
✓ Branch 0 taken 8883 times.
✓ Branch 1 taken 26785 times.
35668 if (destdmap != -1)
6113 8883 zapp_reporting_set_tag("dmap", destdmap);
6114
6115 35668 int32_t orig_destdmap = destdmap;
6116
2/2
✓ Branch 0 taken 8883 times.
✓ Branch 1 taken 26785 times.
35668 if (destdmap < 0) destdmap = cur_dmap;
6117
6118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35668 times.
35668 if (replay_is_active())
6119 {
6120
1/2
✓ Branch 0 taken 35668 times.
✗ Branch 1 not taken.
35668 if (replay_get_mode() == ReplayMode::ManualTakeover)
6121 replay_stop_manual_takeover();
6122
6123
2/2
✓ Branch 0 taken 26785 times.
✓ Branch 1 taken 8883 times.
35668 if (orig_destdmap != -1)
6124 {
6125
2/2
✓ Branch 0 taken 7809 times.
✓ Branch 1 taken 1074 times.
8883 if (strlen(DMaps[orig_destdmap].name) > 0)
6126 {
6127
1/2
✓ Branch 0 taken 7809 times.
✗ Branch 1 not taken.
7809 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6128 7809 }
6129 else
6130 {
6131
1/2
✓ Branch 0 taken 1074 times.
✗ Branch 1 not taken.
1074 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6132 }
6133 8883 }
6134 35668 replay_step_comment_loadscr(screen);
6135
6136 // Reset the rngs and frame count so that recording steps can be modified without impacting
6137 // behavior of later screens.
6138 35668 replay_sync_rng();
6139 35668 }
6140
6141
2/2
✓ Branch 0 taken 1700390 times.
✓ Branch 1 taken 35668 times.
1736058 for (auto& state : get_screen_states())
6142 1700390 state.second.triggered_secrets = false;
6143 35668 slopes.clear();
6144 35668 Hero.clear_platform_ffc();
6145 35668 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6146 35668 clear_darkroom_bitmaps();
6147 35668 msgscr = nullptr;
6148
6149
2/2
✓ Branch 0 taken 49886293 times.
✓ Branch 1 taken 35668 times.
49921961 for (word x=0; x<animated_combos; x++)
6150 {
6151
2/2
✓ Branch 0 taken 20648698 times.
✓ Branch 1 taken 29237595 times.
49886293 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6152 {
6153 20648698 combobuf[animated_combo_table4[x][0]].aclk = 0;
6154 20648698 }
6155 49886293 }
6156 35668 reset_combo_animations2();
6157 35668 region_is_lit = false;
6158
6159 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6160 // of the new ones.
6161 35668 bool origin_ffc_overlay = false;
6162
2/2
✓ Branch 0 taken 34530 times.
✓ Branch 1 taken 1138 times.
35668 if (origin_scr)
6163 {
6164
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34528 times.
34530 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6165 {
6166 34528 int c = origin_scr->numFFC();
6167
2/2
✓ Branch 0 taken 34384 times.
✓ Branch 1 taken 1032895 times.
1067279 for (int i = 0; i < c; i++)
6168 {
6169
2/2
✓ Branch 0 taken 1032751 times.
✓ Branch 1 taken 144 times.
1032895 if (origin_scr->ffcs[i].flags&ffc_carryover)
6170 {
6171 144 origin_ffc_overlay = true;
6172 144 break;
6173 }
6174 1032751 }
6175 34528 }
6176
6177
3/4
✓ Branch 0 taken 34530 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34386 times.
34530 if (origin_screen_overlay || origin_ffc_overlay)
6178 {
6179
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6180 {
6181 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6182
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6183 1008 prev_origin_scrs[i] = *prev_scr;
6184 else
6185 prev_origin_scrs[i] = {};
6186 1008 }
6187 144 }
6188 34530 }
6189
6190 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6191 // them, but scripts that need their data to persist will be removed.
6192 35668 loadscr_ffc_script_ids_to_remove.clear();
6193
2/2
✓ Branch 0 taken 74510010 times.
✓ Branch 1 taken 35668 times.
74545678 for (auto& key : scriptEngineDatas | std::views::keys)
6194 {
6195
2/2
✓ Branch 0 taken 73394089 times.
✓ Branch 1 taken 1115921 times.
74510010 if (key.first == ScriptType::FFC)
6196 1115921 loadscr_ffc_script_ids_to_remove.insert(key.second);
6197 }
6198
6199 35668 load_region(destdmap, screen);
6200
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 34762 times.
35668 home_screen = screen >= 0x80 ? hero_screen : cur_screen;
6201 35668 hero_screen = screen;
6202
6203 35668 cpos_clear_all();
6204 35668 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6205 35668 FFCore.clear_combo_scripts();
6206
6207
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35504 times.
35668 if (is_in_scrolling_region())
6208 {
6209
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6210 {
6211
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6212 {
6213
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6214
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6215 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6216 1408 }
6217 20992 }
6218 164 }
6219 else
6220 {
6221 35504 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6222 }
6223
6224 35668 prepare_current_region_handles();
6225
6226
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35504 times.
35668 if (is_in_scrolling_region())
6227 {
6228
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6229 {
6230
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6231 {
6232 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6233 1408 }
6234 20992 }
6235 164 }
6236 else
6237 {
6238 35504 load_a_screen_and_layers_post(destdmap, screen, ldir);
6239 }
6240
6241 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6242
2/2
✓ Branch 0 taken 34762 times.
✓ Branch 1 taken 906 times.
35668 if (screen >= 0x80)
6243
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 431 times.
906 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6244
6245 35668 update_slope_comboposes();
6246 35668 cpos_force_update();
6247 35668 trig_trigger_groups();
6248
6249
2/2
✓ Branch 0 taken 1115647 times.
✓ Branch 1 taken 35668 times.
1151315 for (int index : loadscr_ffc_script_ids_to_remove)
6250 {
6251 1115647 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6252 }
6253
6254 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6255 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6256 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6257 // It is up to the quest designer to make their subscreen be actually transparent.
6258 //
6259 // When not in "extended height mode" (otherwise 56 is 0):
6260 // - playing_field_offset: 56, but changes during earthquakes
6261 // - original_playing_field_offset: always 56
6262 //
6263 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6264 // - yofs of sprites
6265 // - bitmap y offsets in draw_screen
6266 // - drawing offsets for putscr, do_layer
6267 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6268 // - lots more
6269 //
6270 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6271
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35526 times.
35668 if (is_extended_height_mode())
6272 {
6273 142 playing_field_offset = 0;
6274 142 original_playing_field_offset = 0;
6275 // A few sprites exist as globals, so we must manually reset them.
6276 142 Hero.yofs = 0;
6277 142 mblock2.yofs = 0;
6278 142 }
6279 else
6280 {
6281 35526 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6282 35526 original_playing_field_offset = 56;
6283 }
6284 35668 is_any_room_dark = is_any_dark();
6285
6286 35668 game->load_portal();
6287 35668 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6288
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35633 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35668 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6289 {
6290 delete Hero.lift_wpn;
6291 Hero.lift_wpn = nullptr;
6292 }
6293
6294 35668 enemy_spawning_has_checked_been_here = false;
6295 35668 markBmap(-1, hero_screen);
6296 35668 Hero.maybe_begin_advanced_maze();
6297 35668 }
6298
6299 // Don't use this directly! Use `loadscr` instead.
6300 906 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6301 {
6302
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6303
6304 906 mapscr previous_scr = *special_warp_return_scr;
6305 906 mapscr* scr = special_warp_return_scr;
6306
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 const mapscr* source = get_canonical_scr(cur_map, screen);
6307
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 *scr = *source;
6308
6309
2/2
✓ Branch 0 taken 5436 times.
✓ Branch 1 taken 906 times.
6342 for (int i = 1; i <= 6; i++)
6310 {
6311
2/2
✓ Branch 0 taken 382 times.
✓ Branch 1 taken 5054 times.
5436 if (scr->layermap[i-1] > 0)
6312
2/4
✓ Branch 0 taken 382 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 382 times.
✗ Branch 3 not taken.
382 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6313 else
6314 5054 special_warp_return_scrs[i] = {};
6315 5436 }
6316
6317 906 scr->valid |= mVALID; //layer 0 is always valid
6318
6319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 906 times.
906 if ( source->script > 0 )
6320 {
6321 scr->script = source->script;
6322 for ( int32_t q = 0; q < 8; q++ )
6323 {
6324 scr->screeninitd[q] = source->screeninitd[q];
6325 }
6326 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6327 }
6328 else
6329 {
6330 906 scr->script = 0;
6331 }
6332
6333
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 if(overlay)
6334 {
6335 for(int32_t c=0; c< 176; ++c)
6336 {
6337 if(scr->data[c]==0)
6338 {
6339 scr->data[c]=previous_scr.data[c];
6340 scr->sflag[c]=previous_scr.sflag[c];
6341 scr->cset[c]=previous_scr.cset[c];
6342 }
6343 }
6344
6345 for(int32_t i=0; i<6; i++)
6346 {
6347 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6348 {
6349 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6350 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6351
6352 for(int32_t c=0; c< 176; ++c)
6353 {
6354 if(TheMaps[lm].data[c]==0)
6355 {
6356 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6357 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6358 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6359 }
6360 }
6361 }
6362 }
6363 }
6364
6365
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
29867 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6366
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 int c = scr->numFFC();
6367
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 28961 times.
29867 for (word i = 0; i < c; i++)
6368 {
6369 28961 scr->ffcs[i].screen_spawned = screen;
6370
1/2
✓ Branch 0 taken 28961 times.
✗ Branch 1 not taken.
28961 scr->ffcs[i].x += offx;
6371
1/2
✓ Branch 0 taken 28961 times.
✗ Branch 1 not taken.
28961 scr->ffcs[i].y += offy;
6372 28961 }
6373
6374 906 int mi = mapind(cur_map, screen);
6375
6376 // Apply perm secrets, if applicable.
6377
3/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 370 times.
906 if(canPermSecret(destdmap,screen))
6378 {
6379
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6380 {
6381
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6382
6383
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6384
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6385 204 bool do_replay_comment = true;
6386 204 bool from_active_screen = false;
6387
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6388 204 }
6389
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6390 {
6391 for (int layer = 0; layer <= 6; layer++)
6392 {
6393 mapscr* tscr = &special_warp_return_scrs[layer];
6394 for (int pos = 0; pos < 176; pos++)
6395 {
6396 newcombo const* cmb = &combobuf[tscr->data[pos]];
6397 if(cmb->type == cLIGHTTARGET)
6398 {
6399 if(!(cmb->usrflags&cflag1)) //Unlit version
6400 {
6401 tscr->data[pos] += 1;
6402 }
6403 }
6404 }
6405 }
6406 }
6407 536 }
6408
6409 screen_handles_t screen_handles;
6410
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 6342 times.
7248 for (int i = 0; i <= 6; i++)
6411
3/4
✓ Branch 0 taken 6342 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1287 times.
✓ Branch 3 taken 5055 times.
6342 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6412
6413
2/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 906 times.
✗ Branch 3 not taken.
906 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6414
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 toggle_gswitches_load(screen_handles);
6415
6416
3/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 901 times.
906 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6417 {
6418
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6419 5 }
6420
6421
3/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 905 times.
906 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6422 {
6423
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6424 1 }
6425
6426
2/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 906 times.
906 if(game->maps[mi]&mCHEST) // if special stuff done before
6427 {
6428 remove_chests(screen_handles);
6429 }
6430
6431
2/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 906 times.
906 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6432 {
6433 remove_lockedchests(screen_handles);
6434 }
6435
6436
2/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 906 times.
906 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6437 {
6438 remove_bosschests(screen_handles);
6439 }
6440
6441
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 clear_xdoors(screen_handles, true);
6442
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 clear_xstatecombos(screen_handles, true);
6443
6444 // check doors
6445
3/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 370 times.
✓ Branch 3 taken 536 times.
906 if (isdungeon(destdmap, screen))
6446 {
6447
2/2
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 370 times.
1850 for(int32_t i=0; i<4; i++)
6448 {
6449 1480 int32_t door=scr->door[i];
6450
6451
4/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 1291 times.
1480 switch(door)
6452 {
6453 case d1WAYSHUTTER:
6454 case dSHUTTER:
6455
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1291 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1291 if ((ldir^1)==i && screen == home_screen)
6456 {
6457 scr->door[i]=dOPENSHUTTER;
6458 }
6459
6460
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1186 times.
1291 get_screen_state(screen).open_doors = -4;
6461 105 break;
6462
6463 case dLOCKED:
6464
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 11 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6465 {
6466 80 scr->door[i]=dUNLOCKED;
6467 80 }
6468
6469 91 break;
6470
6471 case dBOSS:
6472
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6473 {
6474 5 scr->door[i]=dOPENBOSS;
6475 5 }
6476
6477 9 break;
6478
6479 case dBOMB:
6480
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 38 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6481 {
6482 51 scr->door[i]=dBOMBED;
6483 51 }
6484
6485 89 break;
6486 }
6487
6488
2/2
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 1186 times.
294 update_door(scr, i, scr->door[i]);
6489
6490
4/4
✓ Branch 0 taken 1386 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1375 times.
1480 if(door==dSHUTTER||door==d1WAYSHUTTER)
6491 {
6492 105 scr->door[i]=door;
6493 105 }
6494 1480 }
6495 370 }
6496
6497
2/2
✓ Branch 0 taken 6902 times.
✓ Branch 1 taken 544 times.
7248 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6498 {
6499
4/4
✓ Branch 0 taken 5436 times.
✓ Branch 1 taken 1466 times.
✓ Branch 2 taken 2754 times.
✓ Branch 3 taken 2682 times.
6902 if (j<0 || scr->layermap[j] > 0)
6500 {
6501
4/4
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 382 times.
✓ Branch 2 taken 381 times.
✓ Branch 3 taken 1 times.
4220 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6502 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6503
6504
2/2
✓ Branch 0 taken 224316 times.
✓ Branch 1 taken 3660 times.
227976 for(int32_t i=0; i<176; ++i)
6505 {
6506 224316 int32_t c=layerscreen->data[i];
6507
6508 // New screen flag: Cycle Combos At Screen Init
6509
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 224310 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2372 times.
✓ Branch 7 taken 2372 times.
224316 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6510 {
6511 2372 int32_t r = 0;
6512
6513
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2372 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2372 while(combobuf[c].can_cycle() && r++ < 10)
6514 {
6515 newcombo const& cmb = combobuf[c];
6516 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6517 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6518 layerscreen->data[i] = cid;
6519 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6520 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6521 c = layerscreen->data[i];
6522 }
6523 }
6524 226688 }
6525 3660 }
6526 6342 }
6527 5288 }
6528
6529 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6530 // instead returns an array of mapscr.
6531 // Used to draw/save the map.
6532 45151 std::array<mapscr, 7> loadscr2(int32_t screen)
6533 {
6534 45151 std::array<mapscr, 7> scrs;
6535 45151 mapscr* scr = &scrs[0];
6536
6537
2/2
✓ Branch 0 taken 63305867 times.
✓ Branch 1 taken 45151 times.
63351018 for(word x=0; x<animated_combos; x++)
6538 {
6539
2/2
✓ Branch 0 taken 31301377 times.
✓ Branch 1 taken 32004490 times.
63305867 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6540 {
6541 32004490 combobuf[animated_combo_table4[x][0]].aclk=0;
6542 32004490 }
6543 63305867 }
6544
6545
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 const mapscr* source = get_canonical_scr(cur_map, screen);
6546
2/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45151 times.
✗ Branch 3 not taken.
45151 if (!source->is_valid())
6547 {
6548 scrs[0].valid = 0;
6549 return scrs;
6550 }
6551
6552
2/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45151 times.
✗ Branch 3 not taken.
45151 *scr = *get_canonical_scr(cur_map, screen);
6553
2/2
✓ Branch 0 taken 270906 times.
✓ Branch 1 taken 45151 times.
316057 for (int i = 1; i <= 6; i++)
6554 {
6555
2/2
✓ Branch 0 taken 63587 times.
✓ Branch 1 taken 207319 times.
270906 if (scr->layermap[i-1] > 0)
6556
2/4
✓ Branch 0 taken 63587 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63587 times.
✗ Branch 3 not taken.
63587 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6557 else
6558 207319 scrs[i] = {};
6559 270906 }
6560
6561 screen_handles_t screen_handles;
6562
2/2
✓ Branch 0 taken 45151 times.
✓ Branch 1 taken 316057 times.
361208 for (int i = 0; i < 7; i++)
6563
3/4
✓ Branch 0 taken 316057 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102034 times.
✓ Branch 3 taken 214023 times.
316057 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6564
6565 45151 int mi = mapind(cur_map, screen);
6566
6567
3/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45097 times.
✓ Branch 3 taken 54 times.
45151 if(canPermSecret(-1,screen))
6568 {
6569
3/4
✓ Branch 0 taken 45097 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5674 times.
✓ Branch 3 taken 39423 times.
45097 if(game->maps[mi]&mSECRET) // if special stuff done before
6570 {
6571
1/2
✓ Branch 0 taken 5674 times.
✗ Branch 1 not taken.
5674 reveal_hidden_stairs(scr, screen, false);
6572 5674 bool from_active_screen = false;
6573 5674 bool do_replay_comment = true;
6574
1/2
✓ Branch 0 taken 5674 times.
✗ Branch 1 not taken.
5674 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6575 5674 }
6576
3/4
✓ Branch 0 taken 45097 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45080 times.
✓ Branch 3 taken 17 times.
45097 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6577 {
6578
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6579 {
6580 119 mapscr* tscr = &scrs[layer];
6581
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6582 {
6583 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6584
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6585 {
6586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6587 {
6588 17 tscr->data[pos] += 1;
6589 17 }
6590 17 }
6591 20944 }
6592 119 }
6593 17 }
6594 45097 }
6595
6596
3/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231 times.
✓ Branch 3 taken 44920 times.
45151 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6597 {
6598
1/2
✓ Branch 0 taken 231 times.
✗ Branch 1 not taken.
231 remove_lockblocks(screen_handles);
6599 231 }
6600
6601
3/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45150 times.
45151 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6602 {
6603
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6604 1 }
6605
6606
3/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45050 times.
45151 if(game->maps[mi]&mCHEST) // if special stuff done before
6607 {
6608
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6609 101 }
6610
6611
3/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45127 times.
45151 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6612 {
6613
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6614 24 }
6615
6616
2/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45151 times.
45151 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6617 {
6618 remove_bosschests(screen_handles);
6619 }
6620
6621
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 clear_xdoors(screen_handles);
6622
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 clear_xstatecombos(screen_handles);
6623
6624 // check doors
6625
3/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 45097 times.
45151 if (isdungeon(screen))
6626 {
6627
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6628 {
6629 216 int32_t door=scr->door[i];
6630 216 bool putit=true;
6631
6632
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6633 {
6634 case d1WAYSHUTTER:
6635 case dSHUTTER:
6636 61 break;
6637
6638 case dLOCKED:
6639
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6640 {
6641 12 scr->door[i]=dUNLOCKED;
6642 12 }
6643
6644 12 break;
6645
6646 case dBOSS:
6647
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6648 {
6649 scr->door[i]=dOPENBOSS;
6650 }
6651
6652 4 break;
6653
6654 case dBOMB:
6655 if(game->maps[mi]&(mDOOR_UP<<i))
6656 {
6657 scr->door[i]=dBOMBED;
6658 }
6659
6660 break;
6661 }
6662
6663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6664 {
6665
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6666 216 }
6667
6668
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6669 {
6670 61 scr->door[i]=door;
6671 61 }
6672 216 }
6673 54 }
6674
6675
2/2
✓ Branch 0 taken 316057 times.
✓ Branch 1 taken 45151 times.
361208 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6676 {
6677
4/4
✓ Branch 0 taken 270906 times.
✓ Branch 1 taken 45151 times.
✓ Branch 2 taken 63587 times.
✓ Branch 3 taken 207319 times.
316057 if (j < 0 || scr->layermap[j] > 0)
6678 {
6679
2/2
✓ Branch 0 taken 63587 times.
✓ Branch 1 taken 45151 times.
108738 mapscr *layerscreen= (j<0 ? scr
6680 63587 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6681
6682
2/2
✓ Branch 0 taken 19137888 times.
✓ Branch 1 taken 108738 times.
19246626 for(int32_t i=0; i<176; ++i)
6683 {
6684 19137888 int32_t c=layerscreen->data[i];
6685
6686 // New screen flag: Cycle Combos At Screen Init
6687
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19137888 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19137888 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6688 {
6689 int32_t r = 0;
6690
6691 while(combobuf[c].can_cycle() && r++ < 10)
6692 {
6693 newcombo const& cmb = combobuf[c];
6694 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6695 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6696 layerscreen->data[i] = cid;
6697 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6698 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6699 c = layerscreen->data[i];
6700 }
6701 }
6702 19137888 }
6703 108738 }
6704 316057 }
6705
6706 45151 return scrs;
6707
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 }
6708
6709 18920884 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6710 {
6711 // This is a bogus value while screenscrolling == true, but that's ok
6712 // because it is only used to calculate the rpos, and during screenscrolling
6713 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6714 // is always the same no matter the value of scr.
6715 18920884 int screen = get_screen_for_world_xy(x, y);
6716
6717 18920884 x -= viewport.x;
6718 18920884 y -= viewport.y;
6719
6720
3/6
✓ Branch 0 taken 18920884 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18920884 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 18920884 times.
18920884 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6721 {
6722 rectfill(dest,x,y,x+255,y+175,0);
6723 return;
6724 }
6725
6726 37712858 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6727
2/2
✓ Branch 0 taken 128910 times.
✓ Branch 1 taken 18791974 times.
18920884 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6728
6729 int start_x, end_x, start_y, end_y;
6730 18920884 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6731
2/2
✓ Branch 0 taken 18920884 times.
✓ Branch 1 taken 201527004 times.
220447888 for (int cy = start_y; cy < end_y; cy++)
6732 {
6733
2/2
✓ Branch 0 taken 3060458002 times.
✓ Branch 1 taken 201527004 times.
3261985006 for (int cx = start_x; cx < end_x; cx++)
6734 {
6735 3060458002 int i = cx + cy*16;
6736
2/2
✓ Branch 0 taken 356052934 times.
✓ Branch 1 taken 2704405068 times.
3060458002 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6737 3060458002 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6738 3060458002 }
6739 201527004 }
6740 18920884 }
6741
6742 15462873 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6743 {
6744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15462873 times.
15462873 if (!show_layers[0])
6745 {
6746 return;
6747 }
6748
6749 15462873 x -= viewport.x;
6750 15462873 y -= viewport.y;
6751
6752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15462873 times.
31062064 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6753 15599191 mapscr* scr = screen_handles[0].base_scr;
6754
1/2
✓ Branch 0 taken 15599191 times.
✗ Branch 1 not taken.
15599191 if (!scr->is_valid())
6755 return;
6756
6757
2/2
✓ Branch 0 taken 122929 times.
✓ Branch 1 taken 15476262 times.
15599191 if(scr->door[0]==dBOMBED)
6758 {
6759 122929 over_door(scr, dest, 39, up, offx+x, offy+y);
6760 122929 }
6761
6762
2/2
✓ Branch 0 taken 141704 times.
✓ Branch 1 taken 15457487 times.
15599191 if(scr->door[1]==dBOMBED)
6763 {
6764 141704 over_door(scr, dest, 135, down, offx+x, offy+y);
6765 141704 }
6766
6767
2/2
✓ Branch 0 taken 155093 times.
✓ Branch 1 taken 15444098 times.
15599191 if(scr->door[2]==dBOMBED)
6768 {
6769 155093 over_door(scr, dest, 66, left, offx+x, offy+y);
6770 155093 }
6771
6772
2/2
✓ Branch 0 taken 132228 times.
✓ Branch 1 taken 15466963 times.
15599191 if(scr->door[3]==dBOMBED)
6773 {
6774 132228 over_door(scr, dest, 77, right, offx+x, offy+y);
6775 132228 }
6776 15599191 });
6777 15462873 }
6778
6779 3321693 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6780 {
6781
2/4
✓ Branch 0 taken 3321693 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3321693 times.
✗ Branch 3 not taken.
3321693 if (!scr->is_valid() || !show_layers[0])
6782 return;
6783
6784 3321693 x -= viewport.x;
6785 3321693 y -= viewport.y;
6786
6787
2/2
✓ Branch 0 taken 37490 times.
✓ Branch 1 taken 3284203 times.
3321693 if(scr->door[0]==dBOMBED)
6788 {
6789 37490 over_door(scr,dest,39,up,x,y);
6790 37490 }
6791
6792
2/2
✓ Branch 0 taken 36263 times.
✓ Branch 1 taken 3285430 times.
3321693 if(scr->door[1]==dBOMBED)
6793 {
6794 36263 over_door(scr,dest,135,down,x,y);
6795 36263 }
6796
6797
2/2
✓ Branch 0 taken 40175 times.
✓ Branch 1 taken 3281518 times.
3321693 if(scr->door[2]==dBOMBED)
6798 {
6799 40175 over_door(scr,dest,66,left,x,y);
6800 40175 }
6801
6802
2/2
✓ Branch 0 taken 36931 times.
✓ Branch 1 taken 3284762 times.
3321693 if(scr->door[3]==dBOMBED)
6803 {
6804 36931 over_door(scr,dest,77,right,x,y);
6805 36931 }
6806 3321693 }
6807 231299390 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
6808 {
6809 231299390 zfix cmb_z, cmb_z_step;
6810
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 231206601 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
231299390 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
6811 {
6812 3970 cmb_z = zslongToFix(cmb.attributes[2]);
6813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
6814 3970 }
6815
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 231293437 times.
231295420 else if(cmb.genflags & cflag3)
6816 {
6817 1983 cmb_z = cmb.z_height;
6818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
6819 1983 }
6820 231293437 else return false;
6821
6822
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
✓ Branch 2 taken 4804 times.
✓ Branch 3 taken 1149 times.
5953 return (standing_z_state < 0 || (cmb_z>0 && (cmb_z - cmb_z_step) <= standing_z_state));
6823 231299390 }
6824 55966741 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6825 {
6826 55966741 return _walkflag(zx,zy,cnt,0_zf);
6827 }
6828
6829 132441146 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
6830 {
6831 132441146 int x = zx.getRound(), y = zy.getRound();
6832 132441146 int pos = COMBOPOS(x % 256, y % 176);
6833 132441146 const newcombo& c = combobuf[s0->data[pos]];
6834 132441146 const newcombo& c1 = combobuf[s1->data[pos]];
6835 132441146 const newcombo& c2 = combobuf[s2->data[pos]];
6836
4/4
✓ Branch 0 taken 130455489 times.
✓ Branch 1 taken 1985657 times.
✓ Branch 2 taken 130446029 times.
✓ Branch 3 taken 9460 times.
265084580 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6837
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 130547164 times.
✓ Branch 2 taken 2092025 times.
✓ Branch 3 taken 4245 times.
132441146 (iswater_type(c2.type))) && DRIEDLAKE);
6838 132643434 int32_t b=1;
6839
2/2
✓ Branch 0 taken 65402200 times.
✓ Branch 1 taken 67241234 times.
132643434 if(x&8) b<<=2;
6840
2/2
✓ Branch 0 taken 61987004 times.
✓ Branch 1 taken 70656430 times.
132643434 if(y&8) b<<=1;
6841
6842 132643434 int32_t cwalkflag = c.walk;
6843
4/4
✓ Branch 0 taken 132542290 times.
✓ Branch 1 taken 101144 times.
✓ Branch 2 taken 132542126 times.
✓ Branch 3 taken 164 times.
132643434 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
6844
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 132592698 times.
✓ Branch 2 taken 2086801 times.
✓ Branch 3 taken 2036229 times.
✓ Branch 4 taken 2086801 times.
✓ Branch 5 taken 132542126 times.
✓ Branch 6 taken 2086801 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2086801 times.
✗ Branch 9 not taken.
132643270 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6845
2/2
✓ Branch 0 taken 63456231 times.
✓ Branch 1 taken 69086059 times.
132542290 if (s1 != s0)
6846 {
6847
3/4
✓ Branch 0 taken 69086059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69085441 times.
✓ Branch 3 taken 618 times.
69086059 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
6848
4/10
✓ Branch 0 taken 11728 times.
✓ Branch 1 taken 69073713 times.
✓ Branch 2 taken 11728 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11728 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69085441 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6849
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69022535 times.
69085441 else if (c1.type == cBRIDGE)
6850 {
6851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6852 {
6853 62906 int efflag = (c1.walk & 0xF0)>>4;
6854 62906 int newsolid = (c1.walk & 0xF);
6855 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6856 62906 }
6857 else cwalkflag &= c1.walk;
6858 62906 }
6859
3/8
✓ Branch 0 taken 11728 times.
✓ Branch 1 taken 69010807 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11728 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69022535 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6860 69022535 else cwalkflag |= c1.walk;
6861 69086059 }
6862
2/2
✓ Branch 0 taken 102871249 times.
✓ Branch 1 taken 29671041 times.
132542290 if (s2 != s0)
6863 {
6864
2/4
✓ Branch 0 taken 29671041 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29671041 times.
✗ Branch 3 not taken.
29671041 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
6865
4/10
✓ Branch 0 taken 2153 times.
✓ Branch 1 taken 29668888 times.
✓ Branch 2 taken 2153 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2153 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
29671041 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6866
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 29666594 times.
29671041 else if (c2.type == cBRIDGE)
6867 {
6868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6869 {
6870 4447 int efflag = (c2.walk & 0xF0)>>4;
6871 4447 int newsolid = (c2.walk & 0xF);
6872 4447 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6873 4447 }
6874 else cwalkflag &= c2.walk;
6875 4447 }
6876
3/8
✓ Branch 0 taken 2153 times.
✓ Branch 1 taken 29664441 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2153 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29666594 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6877 29666594 else cwalkflag |= c2.walk;
6878 29671041 }
6879
6880
4/4
✓ Branch 0 taken 29430924 times.
✓ Branch 1 taken 103111366 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29429976 times.
132542290 if((cwalkflag&b) && !dried)
6881 29429976 return true;
6882
6883
3/4
✓ Branch 0 taken 103112314 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103095903 times.
✓ Branch 3 taken 16411 times.
103112314 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6884
6885 103095903 return false;
6886 132542290 }
6887
6888 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6889 132542290 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
6890 {
6891 132542290 int x = zx.getRound(), y = zy.getRound();
6892 132542290 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6893 132542290 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6894 132542290 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6895
2/2
✓ Branch 0 taken 63456231 times.
✓ Branch 1 taken 69086059 times.
132542290 if (!s1->valid) s1 = s0;
6896
2/2
✓ Branch 0 taken 102871249 times.
✓ Branch 1 taken 29671041 times.
132542290 if (!s2->valid) s2 = s0;
6897 132542290 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
6898 }
6899
6900 128126571 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
6901 {
6902 128126571 int max_x = world_w;
6903 128126571 int max_y = world_h;
6904
2/2
✓ Branch 0 taken 68545213 times.
✓ Branch 1 taken 59581358 times.
128126571 if (!get_qr(qr_LTTPWALK))
6905 {
6906 59581358 max_x -= 7;
6907 59581358 max_y -= 7;
6908 59581358 }
6909
4/4
✓ Branch 0 taken 127855739 times.
✓ Branch 1 taken 270832 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 127772471 times.
128126571 if (x < 0 || y < 0) return false;
6910
2/2
✓ Branch 0 taken 321704 times.
✓ Branch 1 taken 127450767 times.
127772471 if (x >= max_x) return false;
6911
3/4
✓ Branch 0 taken 538214 times.
✓ Branch 1 taken 126912553 times.
✓ Branch 2 taken 538214 times.
✗ Branch 3 not taken.
127450767 if (x >= max_x - 8 && cnt == 2) return false;
6912
2/2
✓ Branch 0 taken 126902331 times.
✓ Branch 1 taken 548436 times.
127450767 if (y >= max_y) return false;
6913
6914
4/4
✓ Branch 0 taken 29328636 times.
✓ Branch 1 taken 97573695 times.
✓ Branch 2 taken 91933736 times.
✓ Branch 3 taken 5639959 times.
126902331 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
6915 128126571 }
6916
6917 98876498 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6918 {
6919 98876498 mapscr* s0 = get_scr_for_world_xy(x, y);
6920 98876498 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6921 98876498 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6922
2/2
✓ Branch 0 taken 51257834 times.
✓ Branch 1 taken 47618664 times.
98876498 if (!s1->valid) s1 = s0;
6923
2/2
✓ Branch 0 taken 17544242 times.
✓ Branch 1 taken 81332256 times.
98876498 if (!s2->valid) s2 = s0;
6924
6925 98876498 int pos = COMBOPOS(x % 256, y % 176);
6926 98876498 const newcombo& c = combobuf[s0->data[pos]];
6927 98876498 const newcombo& c1 = combobuf[s1->data[pos]];
6928 98876498 const newcombo& c2 = combobuf[s2->data[pos]];
6929
4/4
✓ Branch 0 taken 97953758 times.
✓ Branch 1 taken 922740 times.
✓ Branch 2 taken 97952392 times.
✓ Branch 3 taken 1366 times.
197752996 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6930
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 97952392 times.
✓ Branch 2 taken 922270 times.
✓ Branch 3 taken 1836 times.
98876498 (iswater_type(c2.type))) && DRIEDLAKE);
6931 98876498 int32_t b=1;
6932
2/2
✓ Branch 0 taken 49744264 times.
✓ Branch 1 taken 49132234 times.
98876498 if(x&8) b<<=2;
6933
2/2
✓ Branch 0 taken 41719306 times.
✓ Branch 1 taken 57157192 times.
98876498 if(y&8) b<<=1;
6934
6935 98876498 int32_t cwalkflag = (c.walk>>4);
6936
2/2
✓ Branch 0 taken 76082905 times.
✓ Branch 1 taken 22793593 times.
98876498 if (layer == 0) cwalkflag = (c1.walk>>4);
6937
2/2
✓ Branch 0 taken 76084103 times.
✓ Branch 1 taken 22792395 times.
98876498 if (layer == 1) cwalkflag = (c2.walk>>4);
6938 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6939
4/4
✓ Branch 0 taken 51257834 times.
✓ Branch 1 taken 47618664 times.
✓ Branch 2 taken 22207795 times.
✓ Branch 3 taken 29050039 times.
98876498 if (s1 != s0 && layer < 0)
6940 {
6941
2/2
✓ Branch 0 taken 22194389 times.
✓ Branch 1 taken 13406 times.
22207795 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6942 22207795 }
6943
4/4
✓ Branch 0 taken 17544242 times.
✓ Branch 1 taken 81332256 times.
✓ Branch 2 taken 12983365 times.
✓ Branch 3 taken 4560877 times.
98876498 if (s2 != s0 && layer < 1)
6944 {
6945
2/2
✓ Branch 0 taken 12977505 times.
✓ Branch 1 taken 5860 times.
12983365 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6946 12983365 }
6947
6948
2/2
✓ Branch 0 taken 98717244 times.
✓ Branch 1 taken 159254 times.
98876498 return (cwalkflag&b) ? !dried : false;
6949 }
6950
6951 99250436 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6952 {
6953 DCHECK(cnt == 0 || cnt == 1);
6954 99250436 int max_x = world_w;
6955 99250436 int max_y = world_h;
6956
3/4
✓ Branch 0 taken 45565429 times.
✓ Branch 1 taken 53685007 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45565429 times.
99250436 if (!get_qr(qr_LTTPWALK) && !notLink)
6957 {
6958 45565429 max_x -= 7;
6959 45565429 max_y -= 7;
6960 45565429 }
6961
4/4
✓ Branch 0 taken 99249687 times.
✓ Branch 1 taken 749 times.
✓ Branch 2 taken 200 times.
✓ Branch 3 taken 99249487 times.
99250436 if (x < 0 || y < 0) return false;
6962
2/2
✓ Branch 0 taken 814 times.
✓ Branch 1 taken 99248673 times.
99249487 if (x >= max_x) return false;
6963
3/4
✓ Branch 0 taken 519882 times.
✓ Branch 1 taken 98728791 times.
✓ Branch 2 taken 519882 times.
✗ Branch 3 not taken.
99248673 if (x >= max_x - 8 && cnt == 2) return false;
6964
2/2
✓ Branch 0 taken 372175 times.
✓ Branch 1 taken 98876498 times.
99248673 if (y >= max_y) return false;
6965
6966
3/4
✓ Branch 0 taken 98716454 times.
✓ Branch 1 taken 160044 times.
✓ Branch 2 taken 160044 times.
✗ Branch 3 not taken.
98876498 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
6967 99250436 }
6968
6969 // used by mapdata->isSolid(x,y) in ZScript
6970 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6971 {
6972 int x = zx.getRound(), y = zy.getRound();
6973 {
6974 int max_x = 256;
6975 int max_y = 176;
6976 if (!get_qr(qr_LTTPWALK))
6977 {
6978 max_x -= 7;
6979 max_y -= 7;
6980 }
6981 if (x < 0 || y < 0) return false;
6982 if (x >= max_x) return false;
6983 if (x >= max_x - 8 && cnt == 2) return false;
6984 if (y >= max_y) return false;
6985 }
6986
6987 const mapscr *s1, *s2;
6988
6989 if ( m->layermap[0] > 0 )
6990 {
6991 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
6992 }
6993 else s1 = m;
6994
6995 if ( m->layermap[1] > 0 )
6996 {
6997 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
6998 }
6999 else s2 = m;
7000
7001 zfix unused;
7002 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7003 }
7004
7005 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7006 {
7007 DCHECK_LAYER_NEG1_INDEX(layer);
7008 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7009 if (!m->is_valid()) return false;
7010 return _walkflag_layer(x, y, cnt, m);
7011 }
7012
7013 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7014 {
7015 int x = zx.getRound(), y = zy.getRound();
7016
7017 if (!get_qr(qr_LTTPWALK))
7018 {
7019 max_x -= 7;
7020 max_y -= 7;
7021 }
7022 if (x < 0 || y < 0) return false;
7023 if (x >= max_x) return false;
7024 if (x >= max_x - 8 && cnt == 2) return false;
7025 if (y >= max_y) return false;
7026
7027 if(!m) return true;
7028
7029 int pos = COMBOPOS(x%256, y%176);
7030 const newcombo* c = &combobuf[m->data[pos]];
7031 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7032 int32_t b=1;
7033
7034 if(x&8) b<<=2;
7035
7036 if(y&8) b<<=1;
7037
7038 if((c->walk&b) && !dried)
7039 return true;
7040
7041 if(cnt==1) return false;
7042
7043 ++pos;
7044
7045 if(!(x&8))
7046 b<<=2;
7047 else
7048 {
7049 c = &combobuf[m->data[pos]];
7050 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7051 b=1;
7052
7053 if(y&8) b<<=1;
7054 }
7055
7056 return (c->walk&b) ? !dried : false;
7057 }
7058
7059 //Only check the given mapscr*, not its layer 1&2
7060 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7061 {
7062 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7063 }
7064
7065 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7066 {
7067 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7068 }
7069
7070 313446 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7071 {
7072 DCHECK_LAYER_NEG1_INDEX(layer);
7073 313446 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7074
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 311684 times.
313446 if (!m->is_valid()) return false;
7075 311684 return _effectflag_layer(x, y, cnt, m, notLink);
7076 313446 }
7077
7078 375557 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7079 {
7080 375557 int max_x = world_w;
7081 375557 int max_y = world_h;
7082
3/4
✓ Branch 0 taken 47842 times.
✓ Branch 1 taken 327715 times.
✓ Branch 2 taken 47842 times.
✗ Branch 3 not taken.
375557 if (!get_qr(qr_LTTPWALK) && !notLink)
7083 {
7084 max_x -= 7;
7085 max_y -= 7;
7086 }
7087
2/4
✓ Branch 0 taken 375557 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 375557 times.
375557 if (x < 0 || y < 0) return false;
7088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 375557 times.
375557 if (x >= max_x) return false;
7089
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 374348 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
375557 if (x >= max_x - 8 && cnt == 2) return false;
7090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 375557 times.
375557 if (y >= max_y) return false;
7091
7092
1/2
✓ Branch 0 taken 375557 times.
✗ Branch 1 not taken.
375557 if (!m) return true;
7093
7094 375557 int pos = COMBOPOS(x%256, y%176);
7095 375557 const newcombo* c = &combobuf[m->data[pos]];
7096
3/4
✓ Branch 0 taken 375176 times.
✓ Branch 1 taken 381 times.
✓ Branch 2 taken 381 times.
✗ Branch 3 not taken.
375938 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7097 375557 int32_t b=1;
7098
7099
2/2
✓ Branch 0 taken 204141 times.
✓ Branch 1 taken 171416 times.
375557 if(x&8) b<<=2;
7100
7101
2/2
✓ Branch 0 taken 156412 times.
✓ Branch 1 taken 219145 times.
375557 if(y&8) b<<=1;
7102
7103
3/4
✓ Branch 0 taken 306563 times.
✓ Branch 1 taken 68994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 306563 times.
375557 if(((c->walk>>4)&b) && !dried)
7104 306563 return true;
7105
7106
1/2
✓ Branch 0 taken 68994 times.
✗ Branch 1 not taken.
68994 if(cnt==1) return false;
7107
7108 ++pos;
7109
7110 if(!(x&8))
7111 b<<=2;
7112 else
7113 {
7114 c = &combobuf[m->data[pos]];
7115 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7116 b=1;
7117
7118 if(y&8) b<<=1;
7119 }
7120
7121 return ((c->walk>>4)&b) ? !dried : false;
7122 375557 }
7123
7124 811028 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7125 {
7126 811028 int max_x = world_w;
7127 811028 int max_y = world_h;
7128
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 693661 times.
811028 if (!get_qr(qr_LTTPWALK))
7129 {
7130 693661 max_x -= 7;
7131 693661 max_y -= 7;
7132 693661 }
7133
2/4
✓ Branch 0 taken 811028 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 811028 times.
811028 if (x < 0 || y < 0) return false;
7134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 811028 times.
811028 if (x >= max_x) return false;
7135
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 811028 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
811028 if (x >= max_x - 8 && cnt == 2) return false;
7136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 811028 times.
811028 if (y >= max_y) return false;
7137
7138
3/4
✓ Branch 0 taken 16794 times.
✓ Branch 1 taken 794234 times.
✓ Branch 2 taken 794234 times.
✗ Branch 3 not taken.
811028 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7139 811028 }
7140
7141 811028 bool water_walkflag(int32_t x, int32_t y)
7142 {
7143 811028 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7144 811028 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7145 811028 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7146
7147 811028 int32_t b=1;
7148
2/2
✓ Branch 0 taken 413873 times.
✓ Branch 1 taken 397155 times.
811028 if(x&8) b<<=2;
7149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 811028 times.
811028 if(y&8) b<<=1;
7150
7151
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 784651 times.
811028 if(get_qr(qr_NO_SOLID_SWIM))
7152 {
7153
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7154 132 return true;
7155
7156
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7157 292 return true;
7158
7159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7160 return true;
7161 25953 }
7162 else
7163 {
7164
4/4
✓ Branch 0 taken 35880 times.
✓ Branch 1 taken 748771 times.
✓ Branch 2 taken 19540 times.
✓ Branch 3 taken 16340 times.
784651 if((c.walk&b) && !iswater_type(c.type))
7165 16340 return true;
7166
7167
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 768294 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
768311 if((c1.walk&b) && !iswater_type(c1.type))
7168 17 return true;
7169
7170
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 768281 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
768294 if((c2.walk&b) && !iswater_type(c2.type))
7171 13 return true;
7172 }
7173
7174 794234 return false;
7175 811028 }
7176
7177 560362 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7178 {
7179
2/2
✓ Branch 0 taken 90551 times.
✓ Branch 1 taken 469811 times.
560362 if(dlevel)
7180
8/8
✓ Branch 0 taken 468428 times.
✓ Branch 1 taken 1383 times.
✓ Branch 2 taken 465241 times.
✓ Branch 3 taken 3187 times.
✓ Branch 4 taken 463581 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4189 times.
✓ Branch 7 taken 459392 times.
469811 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7181 10419 return true;
7182
7183
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 549941 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
549943 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7184 return true;
7185
7186
8/8
✓ Branch 0 taken 549674 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 549441 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 549240 times.
✓ Branch 5 taken 201 times.
✓ Branch 6 taken 338 times.
✓ Branch 7 taken 548902 times.
549943 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7187 1041 return true;
7188
7189 // for(int32_t i=0; i<4; i++)
7190
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 548061 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
548902 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7191 36 return true;
7192
7193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 548866 times.
548866 if (collide_object(x, y,cnt*8, 1))
7194 return true;
7195
7196 548866 return _walkflag(x,y,cnt);
7197 560362 }
7198
7199 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7200 {
7201 // 16 pixel buffer to account for slopes that are on bordering screens.
7202
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7203 return true;
7204
7205 // for(int32_t i=0; i<4; i++)
7206
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7207 return true;
7208
7209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7210 return true;
7211
7212 12110 return _walkflag(x,y,cnt);
7213 12110 }
7214
7215 37640 void map_bkgsfx(bool on)
7216 {
7217
2/2
✓ Branch 0 taken 37619 times.
✓ Branch 1 taken 21 times.
37640 if(on)
7218 {
7219 37619 cont_sfx(hero_scr->oceansfx);
7220
7221
4/4
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 37251 times.
✓ Branch 2 taken 314 times.
✓ Branch 3 taken 54 times.
37619 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&liBOSS))
7222 314 cont_sfx(hero_scr->bosssfx);
7223 37619 }
7224 else
7225 {
7226 21 adjust_sfx(hero_scr->oceansfx,128,false);
7227 21 adjust_sfx(hero_scr->bosssfx,128,false);
7228
7229
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7230 {
7231
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7232 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7233 114 }
7234 }
7235 37640 }
7236
7237 239 void toggle_switches(dword flags, bool entry)
7238 {
7239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7240
7241 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7242 239 toggle_switches(flags, entry, create_screen_handles(scr));
7243 239 });
7244 239 }
7245 53857 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7246 {
7247
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 53120 times.
53857 if(!flags) return; //No flags to toggle
7248
7249 737 mapscr* m = screen_handles[0].base_scr;
7250 737 int screen = m->screen;
7251 737 bool is_active_screen = is_in_current_region(m);
7252
7253 305041 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7254 304304 byte togglegrid[176] = {0};
7255 304304 mapscr* scr = rpos_handle.scr;
7256 304304 int lyr = rpos_handle.layer;
7257 304304 int pos = rpos_handle.pos;
7258 304304 newcombo const& cmb = combobuf[scr->data[pos]];
7259
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 264880 times.
304304 if(is_active_screen)
7260
1/2
✓ Branch 0 taken 264880 times.
✗ Branch 1 not taken.
367773 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7261
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102893 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7262 }, ctrigSWITCHSTATE);
7263
3/4
✓ Branch 0 taken 303641 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
304304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7264
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 301544 times.
304304 && !(cmb.usrflags & cflag11)) //global state
7265 {
7266
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7267 {
7268 2314 set<int32_t> oldData;
7269 //Increment the combo/cset by the attributes
7270 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7271 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7272
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7273
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7274 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7275
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7276 {
7277 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7278
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7279 {
7280 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7281 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7282 if(oldData.find(cid) != oldData.end())
7283 break;
7284
7285 scr->data[pos] = cid;
7286 if(!(tmp->animflags & AF_CYCLENOCSET))
7287 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7288 oldData.insert(cid);
7289 tmp = &combobuf[cid];
7290 }
7291 238 }
7292 2314 int32_t cmbid = scr->data[pos];
7293
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7294 {
7295 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7296 41 combobuf[cmbid].cur_frame=0;
7297 41 combobuf[cmbid].aclk = 0;
7298
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7299 41 }
7300 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7301
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7303 {
7304
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7305
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7306
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7307
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7308
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7309 return;
7310 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7311
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7312 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7313 return; //This is a switch/block that will be hit later in the loop!
7314 344 set<int32_t> oldData2;
7315 //Increment the combo/cset by the original cmb's attributes
7316
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7317
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7318 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7319
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7320 {
7321 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7322 while(tmp->can_cycle())
7323 {
7324 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7325 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7326 if(oldData2.find(cid) != oldData2.end())
7327 break;
7328
7329 scr_2->data[pos] = cid;
7330 if(!(tmp->animflags & AF_CYCLENOCSET))
7331 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7332 oldData2.insert(cid);
7333 tmp = &combobuf[cid];
7334 }
7335 }
7336 344 int32_t cmbid2 = scr_2->data[pos];
7337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7338 {
7339 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7340 combobuf[cmbid2].cur_frame=0;
7341 combobuf[cmbid2].aclk = 0;
7342 combo_caches::drawing.refresh(cmbid2);
7343 }
7344 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7345 344 }
7346
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7347 446 }
7348 304304 });
7349
7350
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7351 {
7352 newcombo const& cmb = combobuf[mblock2.bcombo];
7353 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7354 {
7355 if(flags&(1<<cmb.attribytes[0]))
7356 {
7357 //Increment the combo/cset by the attributes
7358 int32_t cmbofs = (cmb.attributes[0]/10000L);
7359 int32_t csofs = (cmb.attributes[1]/10000L);
7360 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7361 mblock2.cs = (mblock2.cs + csofs) & 15;
7362 int32_t cmbid = mblock2.bcombo;
7363 if(combobuf[cmbid].animflags & AF_CYCLE)
7364 {
7365 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7366 combobuf[cmbid].cur_frame=0;
7367 combobuf[cmbid].aclk = 0;
7368 combo_caches::drawing.refresh(cmbid);
7369 }
7370 }
7371 }
7372 }
7373
7374
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7375 {
7376 513 int screen_index_offset = get_region_screen_offset(m->screen);
7377 513 word c = m->numFFC();
7378
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7379 {
7380 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7381
1/2
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
363 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7382
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7383 }, ctrigSWITCHSTATE);
7384 334 }
7385 513 }
7386 53857 }
7387
7388 1 void toggle_gswitches(int32_t state, bool entry)
7389 {
7390 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7391 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7392 1 });
7393 1 }
7394 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7395 {
7396 1 bool states[256] = {false};
7397 1 states[state] = true;
7398 1 toggle_gswitches(states, entry, screen_handles);
7399 1 }
7400 15143656 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7401 {
7402
1/2
✓ Branch 0 taken 15143656 times.
✗ Branch 1 not taken.
15143656 if(!states) return;
7403
7404 15143656 auto& combo_cache = combo_caches::gswitch;
7405 15143656 mapscr* base_scr = screen_handles[0].base_scr;
7406 15143656 int screen = base_scr->screen;
7407 15143656 bool is_active_screen = is_in_current_region(base_scr);
7408 15143656 byte togglegrid[176] = {0};
7409
2/2
✓ Branch 0 taken 15143656 times.
✓ Branch 1 taken 106005592 times.
121149248 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7410 {
7411 106005592 mapscr* scr = screen_handles[lyr].scr;
7412
2/2
✓ Branch 0 taken 32081129 times.
✓ Branch 1 taken 73924463 times.
106005592 if (!scr)
7413 73924463 continue;
7414
7415
2/2
✓ Branch 0 taken 32081129 times.
✓ Branch 1 taken 5646278704 times.
5678359833 for(int32_t pos = 0; pos < 176; ++pos)
7416 {
7417 5646278704 int cid = scr->data[pos];
7418 5646278704 auto& mini_cmb = combo_cache.minis[cid];
7419
7420
2/2
✓ Branch 0 taken 92846160 times.
✓ Branch 1 taken 5553432544 times.
5646278704 if (is_active_screen)
7421 {
7422
2/2
✓ Branch 0 taken 5553430662 times.
✓ Branch 1 taken 1882 times.
5553432544 if (mini_cmb.trigger_global_state)
7423 {
7424 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7425
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7427 }, ctrigSWITCHSTATE);
7428 1882 }
7429 5553432544 }
7430
7431
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5646238309 times.
5646278704 if (!mini_cmb.has_global_state)
7432 5646238309 continue;
7433
7434 40395 newcombo const& cmb = combobuf[cid];
7435
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7436 {
7437 if(states[cmb.attribytes[0]])
7438 {
7439 set<int32_t> oldData;
7440 //Increment the combo/cset by the attributes
7441 int32_t cmbofs = (cmb.attributes[0]/10000L);
7442 int32_t csofs = (cmb.attributes[1]/10000L);
7443 oldData.insert(scr->data[pos]);
7444 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7445 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7446 if(entry && (cmb.usrflags&cflag8))
7447 {
7448 newcombo const* tmp = &combobuf[scr->data[pos]];
7449 while(tmp->can_cycle())
7450 {
7451 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7452 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7453 if(oldData.find(cid) != oldData.end())
7454 break;
7455 scr->data[pos] = cid;
7456 if(!(tmp->animflags & AF_CYCLENOCSET))
7457 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7458 oldData.insert(cid);
7459 tmp = &combobuf[cid];
7460 }
7461 }
7462 int32_t cmbid = scr->data[pos];
7463 if(combobuf[cmbid].animflags & AF_CYCLE)
7464 {
7465 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7466 combobuf[cmbid].cur_frame=0;
7467 combobuf[cmbid].aclk = 0;
7468 combo_caches::drawing.refresh(cmbid);
7469 }
7470 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7471 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7472 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7473 {
7474 if(lyr==lyr2) continue;
7475 if(!(cmb.usrflags&(1<<lyr2))) continue;
7476 if(togglegrid[pos]&(1<<lyr2)) continue;
7477 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7478 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7479 continue;
7480 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7481 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7482 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7483 continue; //This is a switch/block that will be hit later in the loop!
7484 set<int32_t> oldData2;
7485 //Increment the combo/cset by the original cmb's attributes
7486 oldData2.insert(scr_2->data[pos]);
7487 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7488 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7489 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7490 {
7491 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7492 while(tmp->can_cycle())
7493 {
7494 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7495 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7496 if(oldData2.find(cid) != oldData2.end())
7497 break;
7498 scr_2->data[pos] = cid;
7499 if(!(tmp->animflags & AF_CYCLENOCSET))
7500 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7501 oldData2.insert(cid);
7502 tmp = &combobuf[cid];
7503 }
7504 }
7505 int32_t cmbid2 = scr_2->data[pos];
7506 if(combobuf[cmbid2].animflags & AF_CYCLE)
7507 {
7508 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7509 combobuf[cmbid2].cur_frame=0;
7510 combobuf[cmbid2].aclk = 0;
7511 combo_caches::drawing.refresh(cmbid2);
7512 }
7513 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7514 }
7515 }
7516 }
7517 40395 }
7518 32081129 }
7519
7520
4/4
✓ Branch 0 taken 547045 times.
✓ Branch 1 taken 14596611 times.
✓ Branch 2 taken 542301 times.
✓ Branch 3 taken 4744 times.
15143656 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7521 {
7522 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7523
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7524 {
7525 if(states[cmb.attribytes[0]])
7526 {
7527 //Increment the combo/cset by the attributes
7528 int32_t cmbofs = (cmb.attributes[0]/10000L);
7529 int32_t csofs = (cmb.attributes[1]/10000L);
7530 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7531 mblock2.cs = (mblock2.cs + csofs) & 15;
7532 int32_t cmbid = mblock2.bcombo;
7533 if(combobuf[cmbid].animflags & AF_CYCLE)
7534 {
7535 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7536 combobuf[cmbid].cur_frame=0;
7537 combobuf[cmbid].aclk = 0;
7538 combo_caches::drawing.refresh(cmbid);
7539 }
7540 }
7541 }
7542 4744 }
7543
7544
2/2
✓ Branch 0 taken 412287 times.
✓ Branch 1 taken 14731369 times.
15143656 if(is_active_screen)
7545 {
7546 14731369 int screen_index_offset = get_region_screen_offset(screen);
7547 14731369 word c = base_scr->numFFC();
7548
2/2
✓ Branch 0 taken 439505632 times.
✓ Branch 1 taken 14731369 times.
454237001 for (int q = 0; q < c; ++q)
7549 {
7550 439505632 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7551
1/2
✓ Branch 0 taken 439505632 times.
✗ Branch 1 not taken.
439734420 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7552
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7553 }, ctrigSWITCHSTATE);
7554 439505632 }
7555 14731369 }
7556 15143656 }
7557 53618 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7558 {
7559 bool states[256];
7560
2/2
✓ Branch 0 taken 13726208 times.
✓ Branch 1 taken 53618 times.
13779826 for(auto q = 0; q < 256; ++q)
7561 {
7562 13726208 states[q] = game->gswitch_timers[q] != 0;
7563 13726208 }
7564 53618 toggle_gswitches(states, true, screen_handles);
7565 53618 }
7566 14700669 void run_gswitch_timers()
7567 {
7568 14700669 bool states[256] = {false};
7569 14700669 auto& m = game->gswitch_timers.mut_inner();
7570
2/2
✓ Branch 0 taken 3759329024 times.
✓ Branch 1 taken 14700669 times.
3774029693 for(auto it = m.begin(); it != m.end();)
7571 {
7572
2/2
✓ Branch 0 taken 3759328424 times.
✓ Branch 1 taken 600 times.
3759329024 if(it->second > 0)
7573
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7574 {
7575 1 states[it->first] = true;
7576 1 it = m.erase(it);
7577 1 continue;
7578 }
7579 3759329023 ++it;
7580 }
7581 29790706 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7582 15090037 toggle_gswitches(states, false, create_screen_handles(scr));
7583 15090037 });
7584 14700669 }
7585 1117 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7586 {
7587
2/2
✓ Branch 0 taken 285952 times.
✓ Branch 1 taken 1117 times.
287069 for(auto q = 0; q < 256; ++q)
7588 {
7589
1/2
✓ Branch 0 taken 285952 times.
✗ Branch 1 not taken.
285952 if(game->gswitch_timers[q] > 0)
7590 game->gswitch_timers[q] = 0;
7591 285952 }
7592 1117 }
7593
7594 /**** View Map ****/
7595
7596 int32_t mapres = 0;
7597 int32_t view_map_show_mode = 3;
7598
7599 123904 bool displayOnMap(int32_t x, int32_t y)
7600 {
7601 123904 int32_t s = (y<<4) + x;
7602 123904 int mi = mapind(cur_map, s);
7603
2/2
✓ Branch 0 taken 67780 times.
✓ Branch 1 taken 56124 times.
123904 if (!(game->maps[mi]&mVISITED))
7604 67780 return false;
7605
7606 // Don't display if not part of DMap
7607
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 40496 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65090 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7608
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7609
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7610
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7611 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7612 10973 return false;
7613 else
7614 45151 return true;
7615 123904 }
7616
7617 968 void ViewMap()
7618 {
7619 968 ViewingMap = true;
7620
7621 968 BITMAP* mappic = NULL;
7622 static double scales[17] =
7623 {
7624 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7625 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7626 };
7627
7628 968 int32_t px = ((8-(cur_screen&15)) << 9) - 256;
7629 968 int32_t py = ((4-(cur_screen>>4)) * 352) - 176;
7630 968 int32_t lx = ((cur_screen&15)<<8) + HeroX()+8;
7631 968 int32_t ly = ((cur_screen>>4)*176) + HeroY()+8;
7632 968 int32_t sc = 6;
7633
7634 968 bool done=false, redraw=true;
7635
7636 968 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7637
7638
1/2
✓ Branch 0 taken 968 times.
✗ Branch 1 not taken.
968 if(!mappic)
7639 {
7640 enter_sys_pal();
7641 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7642 exit_sys_pal();
7643 return;
7644 }
7645
7646 968 clear_to_color(mappic, WHITE);
7647
7648 968 auto prev_viewport = viewport;
7649 968 viewport.x = 0;
7650 968 viewport.y = 0;
7651
7652 // draw the map
7653 968 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7654 968 combotile_add_x = 256;
7655 968 combotile_add_y = 0;
7656
2/2
✓ Branch 0 taken 7744 times.
✓ Branch 1 taken 968 times.
8712 for(int32_t y=0; y<8; y++)
7657 {
7658
2/2
✓ Branch 0 taken 123904 times.
✓ Branch 1 taken 7744 times.
131648 for(int32_t x=0; x<16; x++)
7659 {
7660
2/2
✓ Branch 0 taken 45151 times.
✓ Branch 1 taken 78753 times.
123904 if (!displayOnMap(x, y))
7661 78753 continue;
7662
7663 45151 int screen = map_scr_xy_to_index(x, y);
7664 45151 auto scrs = loadscr2(screen);
7665 45151 mapscr* scr = &scrs[0];
7666
2/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45151 times.
✗ Branch 3 not taken.
45151 if (!scr->is_valid())
7667 continue;
7668
7669 screen_handles_t screen_handles;
7670
2/2
✓ Branch 0 taken 45151 times.
✓ Branch 1 taken 316057 times.
361208 for (int i = 0; i <= 6; i++)
7671
3/4
✓ Branch 0 taken 316057 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102034 times.
✓ Branch 3 taken 214023 times.
316057 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7672
7673 45151 int xx = 0;
7674 45151 int yy = -playing_field_offset;
7675
7676
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45131 times.
45151 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7677 {
7678
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7679
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7680 20 }
7681
7682
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 44976 times.
45151 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7683 {
7684
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7685
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7686 175 }
7687
7688
2/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45151 times.
✗ Branch 3 not taken.
45151 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7689
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7690
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7691
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7692
7693
2/2
✓ Branch 0 taken 45131 times.
✓ Branch 1 taken 20 times.
45151 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7694 {
7695
1/2
✓ Branch 0 taken 45131 times.
✗ Branch 1 not taken.
45131 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7696
1/2
✓ Branch 0 taken 45131 times.
✗ Branch 1 not taken.
45131 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7697 45131 }
7698
7699
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 putscrdoors(scr, screen_bmp, xx, yy);
7700
2/2
✓ Branch 0 taken 41149 times.
✓ Branch 1 taken 4002 times.
45151 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7701 {
7702
1/2
✓ Branch 0 taken 41149 times.
✗ Branch 1 not taken.
41149 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7703
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39367 times.
41149 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7704 {
7705
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7706
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7707 1782 }
7708 41149 }
7709
7710
2/2
✓ Branch 0 taken 44976 times.
✓ Branch 1 taken 175 times.
45151 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7711 {
7712
1/2
✓ Branch 0 taken 44976 times.
✗ Branch 1 not taken.
44976 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7713
1/2
✓ Branch 0 taken 44976 times.
✗ Branch 1 not taken.
44976 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7714 44976 }
7715
7716
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7717
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7718
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7719
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39367 times.
45151 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7720 {
7721
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7722
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7723 5784 }
7724
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7725
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7726
2/4
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45151 times.
45151 if(replay_version_check(40))
7727 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7728
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7729
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7730
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7731
7732
1/2
✓ Branch 0 taken 45151 times.
✗ Branch 1 not taken.
45151 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7733
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45151 times.
45151 }
7734 7744 }
7735
7736 968 viewport = prev_viewport;
7737 968 combotile_add_x = 0;
7738 968 combotile_add_y = 0;
7739
7740 968 destroy_bitmap(screen_bmp);
7741 968 clear_keybuf();
7742 968 pause_all_sfx();
7743
7744 // view it
7745 968 int32_t delay = 0;
7746
7747 968 do
7748 {
7749
2/2
✓ Branch 0 taken 177720 times.
✓ Branch 1 taken 29891 times.
207611 if (replay_version_check(0, 11))
7750 29891 load_control_state();
7751
7752 207611 int32_t step = int32_t(16.0/scales[sc]);
7753 207611 step = (step>>1) + (step&1);
7754 207611 bool r = cRbtn();
7755
7756
1/2
✓ Branch 0 taken 207611 times.
✗ Branch 1 not taken.
207611 if(cLbtn())
7757 {
7758 step <<= 2;
7759 delay = 0;
7760 }
7761
7762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207611 times.
207611 if(r)
7763 {
7764 if(rUp())
7765 {
7766 py+=step;
7767 redraw=true;
7768 }
7769
7770 if(rDown())
7771 {
7772 py-=step;
7773 redraw=true;
7774 }
7775
7776 if(rLeft())
7777 {
7778 px+=step;
7779 redraw=true;
7780 }
7781
7782 if(rRight())
7783 {
7784 px-=step;
7785 redraw=true;
7786 }
7787 }
7788 else
7789 {
7790
2/2
✓ Branch 0 taken 192844 times.
✓ Branch 1 taken 14767 times.
207611 if(Up())
7791 {
7792 14767 py+=step;
7793 14767 redraw=true;
7794 14767 }
7795
7796
2/2
✓ Branch 0 taken 192614 times.
✓ Branch 1 taken 14997 times.
207611 if(Down())
7797 {
7798 14997 py-=step;
7799 14997 redraw=true;
7800 14997 }
7801
7802
2/2
✓ Branch 0 taken 181309 times.
✓ Branch 1 taken 26302 times.
207611 if(Left())
7803 {
7804 26302 px+=step;
7805 26302 redraw=true;
7806 26302 }
7807
7808
2/2
✓ Branch 0 taken 181932 times.
✓ Branch 1 taken 25679 times.
207611 if(Right())
7809 {
7810 25679 px-=step;
7811 25679 redraw=true;
7812 25679 }
7813 }
7814
7815
2/2
✓ Branch 0 taken 186527 times.
✓ Branch 1 taken 21084 times.
207611 if(delay)
7816 21084 --delay;
7817 else
7818 {
7819 186527 bool a = cAbtn();
7820 186527 bool b = cBbtn();
7821
7822
3/4
✓ Branch 0 taken 1717 times.
✓ Branch 1 taken 184810 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1717 times.
186527 if(a && !b)
7823 {
7824
1/2
✓ Branch 0 taken 1717 times.
✗ Branch 1 not taken.
1717 sc=zc_min(sc+1,16);
7825 1717 delay=8;
7826 1717 redraw=true;
7827 1717 }
7828
7829
3/4
✓ Branch 0 taken 921 times.
✓ Branch 1 taken 185606 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 921 times.
186527 if(b && !a)
7830 {
7831
2/2
✓ Branch 0 taken 920 times.
✓ Branch 1 taken 1 times.
921 sc=zc_max(sc-1,0);
7832 921 delay=8;
7833 921 redraw=true;
7834 921 }
7835 }
7836
7837
2/2
✓ Branch 0 taken 207600 times.
✓ Branch 1 taken 11 times.
207611 if(rPbtn())
7838 11 --view_map_show_mode;
7839
7840 207611 px = vbound(px,-4096,4096);
7841 207611 py = vbound(py,-1408,1408);
7842
7843 207611 double scale = scales[sc];
7844
7845
2/2
✓ Branch 0 taken 72421 times.
✓ Branch 1 taken 135190 times.
207611 if(!redraw)
7846 {
7847 135190 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7848 135190 }
7849 else
7850 {
7851 72421 clear_to_color(framebuf,BLACK);
7852 144842 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7853 72421 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7854 72421 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7855
7856 72421 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7857 72421 redraw=false;
7858 }
7859
7860 207611 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7861 207611 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7862
7863
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 200145 times.
207611 if(view_map_show_mode&1)
7864 {
7865 200145 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7866 200145 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7867 200145 }
7868
7869
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 202011 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
207611 if(view_map_show_mode&2 || r)
7870 202011 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7871
7872
1/2
✓ Branch 0 taken 207611 times.
✗ Branch 1 not taken.
207611 if(r)
7873 {
7874 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7875 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7876 }
7877
7878 207611 advanceframe(false, false);
7879
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 177720 times.
207611 if (replay_version_check(11))
7880 177720 load_control_state();
7881
7882
2/2
✓ Branch 0 taken 206644 times.
✓ Branch 1 taken 967 times.
207611 if(getInput(btnS, true, false, true)) //rSbtn
7883 967 done = true;
7884
7885
2/2
✓ Branch 0 taken 968 times.
✓ Branch 1 taken 206643 times.
415222 }
7886
2/2
✓ Branch 0 taken 967 times.
✓ Branch 1 taken 206644 times.
207611 while(!done && !Quit);
7887
7888 968 ViewingMap = false;
7889 968 destroy_bitmap(mappic);
7890 968 resume_all_sfx();
7891 968 }
7892
7893 1069 int32_t onViewMap()
7894 {
7895
4/6
✓ Branch 0 taken 1069 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1069 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 101 times.
✓ Branch 5 taken 968 times.
1069 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7896 {
7897 968 clear_to_color(framebuf,BLACK);
7898 968 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7899 968 advanceframe(true);
7900 968 ViewMap();
7901 968 }
7902
7903 1069 return D_O_K;
7904 }
7905
7906 35612267 bool isGrassType(int32_t type)
7907 {
7908
2/2
✓ Branch 0 taken 34936149 times.
✓ Branch 1 taken 676118 times.
35612267 switch(type)
7909 {
7910 case cTALLGRASS:
7911 case cTALLGRASSNEXT:
7912 case cTALLGRASSTOUCHY:
7913 676118 return true;
7914 }
7915
7916 34936149 return false;
7917 35612267 }
7918
7919 20891 bool isFlowersType(int32_t type)
7920 {
7921
2/2
✓ Branch 0 taken 16551 times.
✓ Branch 1 taken 4340 times.
20891 switch(type)
7922 {
7923 case cFLOWERS:
7924 case cFLOWERSTOUCHY:
7925 4340 return true;
7926 }
7927
7928 16551 return false;
7929 20891 }
7930
7931 bool isGenericType(int32_t type)
7932 {
7933 switch(type)
7934 {
7935 case cTRIGGERGENERIC:
7936 return true;
7937 }
7938
7939 return false;
7940 }
7941
7942 26025 bool isBushType(int32_t type)
7943 {
7944
2/2
✓ Branch 0 taken 20891 times.
✓ Branch 1 taken 5134 times.
26025 switch(type)
7945 {
7946 case cBUSH:
7947 case cBUSHNEXT:
7948 case cBUSHTOUCHY:
7949 case cBUSHNEXTTOUCHY:
7950
7951 5134 return true;
7952 }
7953
7954 20891 return false;
7955 26025 }
7956
7957 bool isSlashType(int32_t type)
7958 {
7959 switch(type)
7960 {
7961 case cSLASH:
7962 case cSLASHITEM:
7963 case cSLASHTOUCHY:
7964 case cSLASHITEMTOUCHY:
7965 case cSLASHNEXT:
7966 case cSLASHNEXTITEM:
7967 case cSLASHNEXTTOUCHY:
7968 case cSLASHNEXTITEMTOUCHY:
7969 return true;
7970 }
7971
7972 return false;
7973 }
7974
7975 15674 bool isCuttableNextType(int32_t type)
7976 {
7977
2/2
✓ Branch 0 taken 9767 times.
✓ Branch 1 taken 5907 times.
15674 switch(type)
7978 {
7979 case cSLASHNEXT:
7980 case cSLASHNEXTITEM:
7981 case cTALLGRASSNEXT:
7982 case cBUSHNEXT:
7983 case cSLASHNEXTTOUCHY:
7984 case cSLASHNEXTITEMTOUCHY:
7985 case cBUSHNEXTTOUCHY:
7986 5907 return true;
7987 }
7988
7989 9767 return false;
7990 15674 }
7991
7992 17515 bool isTouchyType(int32_t type)
7993 {
7994
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11465 times.
17515 switch(type)
7995 {
7996 case cSLASHTOUCHY:
7997 case cSLASHITEMTOUCHY:
7998 case cBUSHTOUCHY:
7999 case cFLOWERSTOUCHY:
8000 case cTALLGRASSTOUCHY:
8001 case cSLASHNEXTTOUCHY:
8002 case cSLASHNEXTITEMTOUCHY:
8003 case cBUSHNEXTTOUCHY:
8004 11465 return true;
8005 }
8006
8007 6050 return false;
8008 17515 }
8009
8010 29245483 bool isCuttableType(int32_t type)
8011 {
8012
2/2
✓ Branch 0 taken 28796427 times.
✓ Branch 1 taken 449056 times.
29245483 switch(type)
8013 {
8014 case cSLASH:
8015 case cSLASHITEM:
8016 case cBUSH:
8017 case cFLOWERS:
8018 case cTALLGRASS:
8019 case cTALLGRASSNEXT:
8020 case cSLASHNEXT:
8021 case cSLASHNEXTITEM:
8022 case cBUSHNEXT:
8023
8024 case cSLASHTOUCHY:
8025 case cSLASHITEMTOUCHY:
8026 case cBUSHTOUCHY:
8027 case cFLOWERSTOUCHY:
8028 case cTALLGRASSTOUCHY:
8029 case cSLASHNEXTTOUCHY:
8030 case cSLASHNEXTITEMTOUCHY:
8031 case cBUSHNEXTTOUCHY:
8032 449056 return true;
8033 }
8034
8035 28796427 return false;
8036 29245483 }
8037
8038 17295 bool isCuttableItemType(int32_t type)
8039 {
8040
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16871 times.
17295 switch(type)
8041 {
8042 case cSLASHITEM:
8043 case cBUSH:
8044 case cFLOWERS:
8045 case cTALLGRASS:
8046 case cTALLGRASSNEXT:
8047 case cSLASHNEXTITEM:
8048 case cBUSHNEXT:
8049
8050 case cSLASHITEMTOUCHY:
8051 case cBUSHTOUCHY:
8052 case cFLOWERSTOUCHY:
8053 case cTALLGRASSTOUCHY:
8054 case cSLASHNEXTITEMTOUCHY:
8055 case cBUSHNEXTTOUCHY:
8056 16871 return true;
8057 }
8058
8059 424 return false;
8060 17295 }
8061
8062 66 bool is_push(mapscr* m, int32_t pos)
8063 {
8064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8065 return true;
8066 66 newcombo const& cmb = combobuf[m->data[pos]];
8067
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8068 return true;
8069
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8070 14 return true;
8071
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8072 return true; //Counts as 'pushblock' flag
8073 52 return false;
8074 66 }
8075
8076 415 static std::map<int, screen_state_t> screen_states;
8077
8078 35668 std::map<int, screen_state_t>& get_screen_states()
8079 {
8080 35668 return screen_states;
8081 }
8082
8083 43964799 screen_state_t& get_screen_state(int screen)
8084 {
8085 43964799 return screen_states[screen];
8086 }
8087
8088 580 void clear_screen_states()
8089 {
8090 580 screen_states.clear();
8091 580 }
8092
8093 1438 void screen_item_set_state(int screen, ScreenItemState state)
8094 {
8095 1438 get_screen_state(screen).item_state = state;
8096 1438 }
8097
8098 36830 void mark_visited(int screen)
8099 {
8100
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 36356 times.
36830 if (screen < 0x80)
8101 {
8102
2/2
✓ Branch 0 taken 24469 times.
✓ Branch 1 taken 11887 times.
36356 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8103 11887 game->maps[mapind(cur_map, screen)] |= mVISITED;
8104
8105 36356 markBmap(-1, screen);
8106 36356 }
8107 36830 }
8108